如何将整数转换为void指针?

在C语言中使用Threads时,我正面临警告

“警告:从不同大小的整数转换为指针”

代码如下

#include #include #include #include void *print(void *id) { int a=10; printf("My thread id is %ld\n",pthread_self()); printf("Thread %d is executing\n",id); return (void *) 42; } int main() { pthread_t th[5]; int t; int i; int status; void *ret; for(i=0;i%d\n",(int *)ret); } pthread_exit(NULL); } 

任何人都可以解释如何将一个整数传递给接收(void *)作为参数的函数吗?

这是将整数传递给新pthread的好方法,如果这是你需要的。 你只需要取消警告,这样就可以了:

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

讨论

这可能会冒犯你的感情,但它很短暂 ,没有竞争条件(如果你使用的话,就像你一样)。 编写几十行额外代码只是为了得到一堆编号的线程没有任何意义。

数据竞赛

这是一个带有数据竞争的糟糕版本:

 #include  #include  #define N 10 void *thread_func(void *arg) { int *ptr = arg; // Has *ptr changed by the time we get here? Maybe! printf("Arg = %d\n", *ptr); return NULL; } int main() { int i; pthread_t threads[N]; for (i = 0; i < N; i++) { // NO NO NO NO this is bad! pthread_create(&threads[i], NULL, thread_func, &i); } for (i = 0; i < N; i++) { pthread_join(threads[i], NULL); } return 0; } 

现在,当我用线程消毒剂运行它时会发生什么?

(另外,看看它如何打印“5”两次...)

 ==================
警告:ThreadSanitizer:数据竞争(pid = 20494)
  通过线程T1在0x7ffc95a834ec读取大小4:
     #0 thread_func /home/depp/test.c:9(a.out + 0x000000000a8c)
     #1  (libtsan.so.0 + 0x000000023519)

  之前通过主线程在0x7ffc95a834ec写入大小4:
     #0 main /home/depp/test.c:17(a.out + 0x000000000b3a)

  位置是主线程的堆栈。

  线程T1(tid = 20496,正在运行)由主线程创建:
     #0 pthread_create (libtsan.so.0 + 0x0000000273d4)
     #1 main /home/depp/test.c:18(a.out + 0x000000000b1c)

摘要:ThreadSanitizer:data race /home/depp/test.c:9 thread_func
 ==================
 Arg = 1
 Arg = 2
 Arg = 3
 Arg = 4
 Arg = 5
 Arg = 6
 Arg = 7
 Arg = 8
 Arg = 9
 Arg = 5
 ThreadSanitizer:报告了1个警告

你可以这样做:

 #include  #include  #include  #include  struct th { pthread_t thread; int id; int ret; }; void *print(void *id) { int a=10; struct th *self = (struct th *) id; printf("My thread id is %ld\n",pthread_self()); printf("Thread %d is executing\n",self->id); self->ret = random(); return; } int main(void) { struct th th[5]; int t; int i; int status; void *ret; for(i=0;i<5;i++) { th[i].id = i; status=pthread_create(&th[i].thread,NULL,print,&th[i]); //Getting warning at this line if(status) { printf("Error creating threads\n"); exit(0); } } for (i=0;i<5;i++) { pthread_join(th[i].thread,&ret); printf("%d--->%d\n",th[i].id,th[i].ret); } pthread_exit(NULL); } 

将输出:

 My thread id is 4496162816 My thread id is 4497870848 My thread id is 4498944000 My thread id is 4498407424 Thread 0 is executing Thread 1 is executing My thread id is 4499480576 Thread 3 is executing Thread 2 is executing 0--->1804289383 Thread 4 is executing 1--->846930886 2--->1714636915 3--->1681692777 4--->1957747793 

传递一个唯一的指针到每个线程不会竞争,你可以获得/保存在该结构中的任何类型的信息

你可以将int值作为void指针传递,如(void *)&n ,其中n是整数,并在函数中接受void指针作为参数,如void foo(void *n); 最后在函数内部将void指针转换为int like, int num = *(int *)n; 。 这样你就不会得到任何警告。

更改:

 status=pthread_create(&th[i],NULL,print,(void *)i); 

至:

 status=pthread_create(&th[i],NULL,print,(reinterpret_cast(i)); 

reinterpret_cast使int成为指针的大小,警告将停止。 基本上它是一个更好的版本(void *)i。