如何将int作为"void*"传递给线程启动函数?

efu*_*ddy 2 c int casting pthreads void

我最初为我的斐波纳契变量数组有一个全局变量,但发现这是不允许的.我需要进行基本的多线程处理并处理竞争条件,但我无法在pthread create中将int作为void参数提供.我试过使用一个没有运气的常量指针.由于一些奇怪的原因,void*超过了第一个布尔测试但不是else,如果:

  $ gcc -o fibonacci fibonacci.c
    fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
      else if (arg == 1)
               ~~~ ^  ~
    1 warning generated.
Run Code Online (Sandbox Code Playgroud)

我的代码很乱,我真的很困惑,因为我已经重写了很多次.如果我将我的线程运行函数中的所有args转换为int,我会得到一个分段错误11,这是有道理的.所有通过地址传递i索引并取消引用它的尝试都失败了,因为它是一个void并且不能用作int.你能推荐别的吗?

#include<stdio.h> //for printf
#include<stdlib.h>  //for malloc
#include<pthread.h> //for threading

#define SIZE 25 //number of fibonaccis to be computed
int *fibResults;  //array to store fibonacci results

void *run(void *arg)  //executes and exits each thread
{
  if (arg == 0)
  {
    fibResults[(int)arg] = 0;
    printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);    
    pthread_exit(0); 
 }

  else if (arg == 1)
  {
    fibResults[(int)arg] = 1;
    printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);   
    pthread_exit(0);  
  }
  else
  {
    fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
    printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
    pthread_exit(0);
  }
}

//main function that drives the program.
int main()
{
  pthread_attr_t a;
  fibResults = (int*)malloc (SIZE * sizeof(int));
  pthread_attr_init(&a);  

  for (int i = 0; i < SIZE; i++)
  {
    pthread_t thread;
    pthread_create(&thread, &a, run,(void*) &i);
    printf("Thread[%d] created\t", i); 
    fflush(stdout);
    pthread_join(thread, NULL);
    printf("Thread[%d] joined & exited\t", i); 
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 5

你不需要在调用中pthread_create()使用强制转换 - 转换void *为自动.

在线程函数中,您可以使用

int i = *(int *)arg;
Run Code Online (Sandbox Code Playgroud)

但是,您现在遇到了同步问题; 所有线程都使用相同的(指向相同的)整数变量,并且由于调度问题,您无法预测它们将看到哪个值.每线程数据需要是"每个线程".

所以,有各种各样的方法.在这种情况下,我可能会使用

#include <stdint.h>
Run Code Online (Sandbox Code Playgroud)

并在main():

    pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
Run Code Online (Sandbox Code Playgroud)

然后在线程函数中:

int i = (uintptr_t)arg;
Run Code Online (Sandbox Code Playgroud)

现在演员 - 双重演员 - 是必要的.强制转换以uintptr_t确保整数值足以容纳指针; void *需要转换为,因为没有任何整数类型的隐式转换void *.这可确保每个线程函数调用具有不同的值.共享指向一个指针,int表示一切都是不受控制的.