0

我遇到了示例代码。

假设_order_of_execution_pitfall.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define N 4

void* hello(void* arg)
{
   printf("Hello World from Thread%d\n", *(int*)arg);
   return NULL;
}

int main()
{
   pthread_t tid[N];
   int i;

   for(i = 0; i < N; i++)
   {
      pthread_create(&tid[i], NULL, hello, (void*)&i); //&i points to same address
   }

   for(i = 0; i < N; i++)
   {
      pthread_join(tid[i], NULL);
   }

   return 0;
}

在这里,它错误地假设线程在创建时就开始执行。printf() 语句确实可以在下一次调用 pthread_create() 之前执行,但是操作系统可以自由地以任何顺序调度线程。有可能所有线程都在它们中的任何一个实际开始执行之前创建。由于 的所有副本都arg指向相同的地址,该地址在 中发生变化main(),因此线程可以打印相同的identification number

我试图通过using a unique address保存每个线程的标识号来更正上面的代码,如下所示

假设_order_of_execution_workaround.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define N 4

void* hello(void* arg)
{
   printf("Hello World from Thread%d\n", *(int*)arg);
   return NULL;
}

int main()
{
   pthread_t tid[N];
   int tno[N];
   int i;

   /* Added code */   
   for(i = 0; i < N; i++)
   {
      tno[i] = i + 1;
   }/* Added code */

   for(i = 0; i < N; i++)
   {
      pthread_create(&tid[i], NULL, hello, (void*)(tno+i)); // providing unique address for each thread
   }

   for(i = 0; i < N; i++)
   {
      pthread_join(tid[i], NULL);
   }

   return 0;
}

我的修正是正确的方法吗?如果有的话,有人可以建议我一种更正确的方法吗?

4

2 回答 2

1

是的,这是正确的做法。

于 2012-08-17T06:19:16.537 回答
1

是的 - 这对我来说是正确的。

于 2012-08-17T06:21:18.740 回答