为什么pthread_join在这个例子中没有正确关闭一个线程数组?

时间:2011-10-25 21:07:44

标签: c pthreads

我正在尝试自学pthreads线程。我有以下源代码,它可以正确编译和运行:

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

#define PTHREAD_COUNT 10
#define FREQ 5

void *thread_function(void *arg) {
  int *incoming = (int *)arg;
  int freqIdx;

  for (freqIdx = 0; freqIdx < FREQ; freqIdx++)
    fprintf(stdout, "Hello, world (thread %d)\n", *incoming);

  return NULL;
}

int main(int argc, char **argv) {
  pthread_t thread_IDs[PTHREAD_COUNT];
  void *exit_status;
  int threadIdx;

  for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) {
    pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &threadIdx);
    pthread_join(thread_IDs[threadIdx], &exit_status);
  }

  return 0;
}

我得到以下结果:

Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 1)
...
Hello, world (thread 9)

如果我在一个循环中pthread_create一个pthread_t类型的数组,然后在一个单独的循环中pthread_join,那么事情就会失败:

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

#define PTHREAD_COUNT 10
#define FREQ 5

void *thread_function(void *arg) {
  int *incoming = (int *)arg;
  int freqIdx;

  for (freqIdx = 0; freqIdx < FREQ; freqIdx++)
    fprintf(stdout, "Hello, world (thread %d)\n", *incoming);

  return NULL;
}

int main(int argc, char **argv) {
  pthread_t thread_IDs[PTHREAD_COUNT];
  void *exit_status;
  int threadIdx;

  /* here I split the thread _create and _join steps into separate loops */

  for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++)
    pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &threadIdx);

  for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++)
    pthread_join(thread_IDs[threadIdx], &exit_status);

  return 0;
}

这个输出是非常错误的。我没有从每个线程中获取五个fprintf语句,而是从线程0和线程2中获得一个或两个,以及从线程0获得大约20到25个Hello, world语句。

为什么这会失败?

3 个答案:

答案 0 :(得分:2)

我看到的一个问题是你给它一个地址变量threadIdx的地址。在循环中修改它时,线程看到的值也会更改。所以threadIdx值不正确。

在第二个循环中,你再次将threadIdx设置为0并等待线程完成,这解释了为什么你会看到很多人打印出线程0而不是。

你可以简单地传递threadIdx,然后将void * args解释为int(因为sizeof(int)&lt; = sizeof(void *)并且通常在大多数机器上得到保证)并且你应该得到正确的输出。< / p>

答案 1 :(得分:1)

将指向同一threadIdx变量的指针传递给所有线程。

答案 2 :(得分:1)

正如其他人所说,你的问题是在所有线程之间共享一个threadIdx变量。解决此问题的一种方法是为每个线程创建一个变量:

int threadIdx;
int indexes[PTHREAD_COUNT];

for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) {
    indexes[threadIdx] = threadIdx;
    pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &indexes[threadIdx]);
}