使用pthread时在struct中传递数组的问题 #包括 #包括 #包括 #包括 #包括 #包括 #包括 /*您可能需要在此处定义struct*/ 结构参数类型{ int头; 整数长度; int-num; 浮动*vec; 双倍*平方和; }; /*! *\brief子例程函数 * *\param arg,输入参数指针 *\return void*,返回指针 */ void*l2_范数(void*arg){ /*TODO:这里是您的代码*/ 结构参数类型*a=(结构参数类型*)参数; a->sqsum[a->num]=0.0f; 对于(int j=a->head;jhead+a->length);j++){ a->sqsum[a->num]+=a->vec[j]*a->vec[j]; } pthread_exit(NULL); } /*! *\brief包装函数 * *\param vec,输入向量数组 *\param len,向量的长度 *\param k,线程数 *\返回浮点,l2范数 */ 浮点多线程l2范数(常量浮点*vec,大小长度,整数k){ /*TODO:这里是您的代码*/ 双和=0.0f; 结构参数\类型参数; pthread_t tid; *arg.vec=*vec; arg.length=(int)len/k; for(int i=0;i

使用pthread时在struct中传递数组的问题 #包括 #包括 #包括 #包括 #包括 #包括 #包括 /*您可能需要在此处定义struct*/ 结构参数类型{ int头; 整数长度; int-num; 浮动*vec; 双倍*平方和; }; /*! *\brief子例程函数 * *\param arg,输入参数指针 *\return void*,返回指针 */ void*l2_范数(void*arg){ /*TODO:这里是您的代码*/ 结构参数类型*a=(结构参数类型*)参数; a->sqsum[a->num]=0.0f; 对于(int j=a->head;jhead+a->length);j++){ a->sqsum[a->num]+=a->vec[j]*a->vec[j]; } pthread_exit(NULL); } /*! *\brief包装函数 * *\param vec,输入向量数组 *\param len,向量的长度 *\param k,线程数 *\返回浮点,l2范数 */ 浮点多线程l2范数(常量浮点*vec,大小长度,整数k){ /*TODO:这里是您的代码*/ 双和=0.0f; 结构参数\类型参数; pthread_t tid; *arg.vec=*vec; arg.length=(int)len/k; for(int i=0;i,c,multithreading,pointers,struct,pthreads,C,Multithreading,Pointers,Struct,Pthreads,我是一个初学者,对这个话题还不熟悉 这是一个程序,使用多个线程计算L2范数,并将时间与原始实现进行比较 在使用GDB之后,我非常确定程序仍然停留在第49行 *arg.vec=*vec 但是我不确定为什么要共享arg变量,并在那里给每个线程一个副本 #include <math.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h>

我是一个初学者,对这个话题还不熟悉

这是一个程序,使用多个线程计算L2范数,并将时间与原始实现进行比较

在使用GDB之后,我非常确定程序仍然停留在第49行

*arg.vec=*vec


但是我不确定为什么要共享arg变量,并在那里给每个线程一个副本

#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>

/* You may need to define struct here */
struct arg_type {
    int head;
    int length;
    int num;
    float *vec;
    double *sqsum;
};

/*!
 * \brief subroutine function
 *
 * \param arg, input arguments pointer
 * \return void*, return pointer
 */
void *l2_norm(void *arg) { 
    /* TODO: Your code here */
    struct arg_type *a = (struct arg_type *)arg;
    a->sqsum[a->num] = 0.0f;
    for (int j = a->head; j < (a->head + a->length); j++) {
        a->sqsum[a->num] += a->vec[j] * a->vec[j];
    }
    pthread_exit(NULL);
}

/*!
 * \brief wrapper function
 *
 * \param vec, input vector array
 * \param len, length of vector
 * \param k, number of threads
 * \return float, l2 norm
 */
float multi_thread_l2_norm(const float *vec, size_t len, int k) { 
    /* TODO: your code here */
    double sum = 0.0f;
    struct arg_type arg;
    pthread_t tid;
    
    *arg.vec = *vec;
    
    arg.length = (int)len / k;
    
    for (int i = 0; i < k; i++) {
        arg.num = i;
        arg.head = arg.length * i;
        pthread_create(&tid, NULL, l2_norm, &arg);
    }
    
    pthread_join(tid, NULL);
    for (int j = 0; j < k; j++) {
        sum += arg.sqsum[j];
    }
    sum = sqrt(sum);
    return sum;
}

在您的情况下,所有线程都将具有相同的arg.num、arg.head…

arg.vec是一个未分配的指针,因此访问内容将崩溃

应该是,

arg.vec=vec

此外,代码中的其他问题包括--

  • 需要arg的数组: 您创建了“k”个线程,但将相同的“arg”结构传递给每个线程,因此“arg”的变量成员(即num,head)在基于并发运行的线程函数中可能是相同的。 因此,您需要“arg”结构的“k”个数,即arg结构的数组,并将其每个元素传递给每个线程

  • 需要阵列tid: 另外,您创建了“k”个线程,但您只加入了一个线程(即最后一个线程),也就是说,您确保只完成最后一个线程。为了确保所有线程都完成,您需要等待所有创建的线程


  • 上面的代码是与问题相关的代码的一部分,我们仍然需要将函数签名更改为
    float multi_thread\u l2_norm(float*vec,size\t len,int k)
    ,因为您声明的结构中的arg.vec成员为非常量,所以将其分配给传入的vec(const)将产生错误。而且,由于您没有在函数中更改vec的内容,所以const是合适的。
    // you need to allocate new memory zone before storing the vec in it
    // ex : arg = malloc(sizeof(arg_type ));
    *arg.vec = *vec;