将循环索引传递给C

时间:2017-02-02 22:52:04

标签: c multithreading pthreads pthread-join

我想通过包装器对象将我的for循环索引传递给pthread_create的参数。但是,线程中的打印整数不正确。 我希望下面的代码可以打印出来,没有特别的顺序。

  

id为0,id为1,id为2,id为3,

然而,它会打印出来,而整数1,3永远不会传递给线程

  

id为0,id为0,id为0,id为2,

struct thread_arg {
 int id;
 void * a;
 void * b;
}

void *run(void *arg) {
 struct thread_arg * input = arg;
 int id = input->id;
 printf("id is %d, ", id)
}

int main(int argc, char **argv) {
 for(int i=0; i<4; i++) {
  struct thread_arg arg;
  arg.id = i;
  arg.a = ...
  arg.b = ...
  pthread_create(&thread[i], NULL, &run, &arg);
 }

}

1 个答案:

答案 0 :(得分:1)

struct thread_arg处于自动存储状态,其范围仅存在于for循环中。此外,在内存中只有其中一个,并且您将相同的一个传递给每个不同的线程。您在修改此相同对象的ID 4不同时间之间创建数据竞争,并在您的工作线程中打印出其ID。此外,一旦存在for循环,该内存超出范围且不再有效。由于您在此处使用线程,因此调度程序可以随意运行您的主线程或任何子线程,因此我希望看到有关打印输出的不一致行为。在将它传递给子线程之前,您需要在每个数组中创建一个struct thread_arg或malloc数组。

#define NUM_THREADS 4

struct thread_arg {
  int id;
  void * a;
  void * b;
}

void *run(void *arg) {
  struct thread_arg * input = arg;
  int id = input->id;
  printf("id is %d, ", id)
}

int main(int argc, char **argv) {
  struct thread_arg args[NUM_THREADS];
  for(int i=0; i<NUM_THREADS; i++) {
    args[i].id = i;
    args[i].a = ...
    args[i].b = ...
    pthread_create(&thread[i], NULL, &run, &args[i]);
  }

  // probably want to join on threads here waiting on them to finish
  return 0;
}