从不同大小的整数,pthread代码转换为指针

我有这个代码用于矩阵乘法,使用pthreads,但我得到错误“从不同大小的整数转换为指针”

我不知道出了什么问题。我是pthread的新手,这是我到目前为止所做的:

#include  #include  #include  #include  #include  #define NTHREADS 4 int dim ; pthread_mutex_t m; /* Mutex protecting the sum value */ pthread_t thread_id[NTHREADS]; /* Thread ids */ float **A, **B, **C; void *prod (void *s){ int *id=(int *)s; int idd=*id; /* Define local variables */ int i,j,k, start, end, len ; float **Aa, **Bb, **Cc; start = dim*idd; /* Start of this threads slice of the vectors */ end = start + dim; /* End of the slice */ for (i = 0 ; i < dim; i++) { for (j = 0; j < dim; j++) { Cc[i][j] = 0; for (i=start; i<end ; i++) { Cc[i][j] += Aa[i][k] * Bb[k][j]; } } } pthread_mutex_lock (&m); /* Lock the mutex */ C[i][j] += Cc[i][j]; /* Update the shared variable */ pthread_mutex_unlock (&m); /* Unlock the mutex */ pthread_exit(NULL); /* Done! */ } int main ( int argc, char *argv[] ) { void *status; float **A, **B, **C; int i,j,k; if ( argc == 2) dim = atoi(argv[1]); // get the dimension of the matrix // from the command prompt else dim = 128; A = (float **)malloc(sizeof(float*)*dim); B = (float **)malloc(sizeof(float*)*dim); C = (float **)malloc(sizeof(float*)*dim); for (i = 0 ; i < dim; i++) { A[i] = (float *)malloc(sizeof(float)*dim); B[i] = (float *)malloc(sizeof(float)*dim); C[i] = (float *)malloc(sizeof(float)*dim); } for (i=0; i<dim; i++) { for (j = 0 ; j < dim; j++) { A[i][j]=rand(); B[i][j]=rand(); } } struct timeval t1, t2; gettimeofday(&t1, NULL); // you need to parallelize this // perform the multiplication for(i=0;i<NTHREADS;i++) { pthread_create(&thread_id[i], NULL, prod, (void *)i); } /* Wait on the other threads */ for(i=0;i<NTHREADS;i++) { pthread_join(thread_id[i], &status); } gettimeofday(&t2, NULL); double t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec ) / 1000000.0; // take the difference and report it in seconds printf("execution time %f seconds\n",t); } 

这一行的错误:

 pthread_create(&thread_id[i], NULL, prod, (void *)i); 

您错误地使用hack将整数传递给线程。 你正在做的事情背后的想法是一个整数是4个字节,指针是x86_32中的4个字节(x86_64中的8个字节)所以我可以将整数类型转换为指针类型,然后将其转换回int类型而不会丢失任何数据。 这适用于大多数场景,但不能保证指针和整数具有相同的大小。 C标准没有规定这一点。

编译器返回一个警告,因为您正在将int转换为void * ,它可能具有不同的大小(但实际上在您的机器中它们具有相同的大小)。

您的代码中存在错误,当您将int转换为void *调用pthead_create函数时,您应该将其转换回整数类型。 所以,这一行是错误的:

 int *id=(int *)s; 

它应该是 :

 int id = (int)s; 

考虑这个示例,其中线程函数的参数为​​零。

 s=0; therefore ---> *id=(int*)0; // Null pointer 

这是指向零地址的指针。 当您尝试遵循它时,您可能会遇到分段错误。

执行此操作的最佳方法是使用intptr_t类型。 此类型在每个体系结构中具有相同大小的指针(不是int)。 它的定义如下:

整数类型,能够保存从void指针转换的值,然后转换回该类型,其值与原始指针的值相等。

所以你可以这样做:

 #include  void *threadfunc(void *param) { int id = (intptr_t) param; ... } int i, r; r = pthread_create(&thread, NULL, threadfunc, (void *) (intptr_t) i); 

(此示例代码取自: 如何将整数转换为void指针? )

但是,不能保证int的大小与intptr_t的大小相同,但转换过程中的某些数据实际上不太可能丢失。

编辑

其他错误:

  • float **Aa, **Bb, **Cc; 没有初始化。
  • startend超出了数组的限制。 矩阵行未分配在连续的存储区中。
  • 如果线程函数正在处理矩阵的块,则没有必要遍历矩阵A和B的所有值。您可能只需要内部循环,理论上,它应该在矩阵分配的部分上工作它。

我会考虑重写矩阵乘法的代码,因为算法是错误的。

实现这一目标的正确方法是引用变量“i”(查看http://man7.org/linux/man-pages/man3/pthread_create.3.html ):

 pthread_create(&thread_id[i], NULL, prod, (void *)&i); 

您想要转换integer,short或char,并使用reinterpret_cast()调用设置指向该值的指针。 我们曾经只是(void *)这个值,而较旧的编译器很高兴,但新版本,例如g ++ 4.8.5,知道值不是指针的正确大小。 reinterpret_cast就像一个演员,但它调整了大小,所以编译不会抱怨。

例如:

 int i = 3; pointer void * ptr; ptr = (void*)i; // will generate the warning ptr = reinterpret_cast(i); // No warning is generated 

X11示例从addr中获取一个字符,然后将XTPOINTER设置为它。

 val = (XTPOINTER)(*(char*)toVal.addr); // warning val = reinterpret_cast(*(short*)toVal.addr); // No warning