为什么在此示例中 pthread_join 没有正确关闭线程数组?

发布于 2024-12-12 02:16:15 字数 2019 浏览 0 评论 0原文

我正在尝试自学 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 语句,而是从线程 2 和 3 获取一两个语句,并从线程 0 获取大约 20 到 25 个 Hello, world 语句为什么

会失败?

I am trying to teach myself pthreads threading. I have the following source, which compiles and runs properly:

#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;
}

I get the following result:

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)

If I pthread_create an array of pthread_t types over a loop, and then pthread_join in a separate loop, then things fail:

#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;
}

The output from this is quite wrong. Instead of getting five fprintf statements from each thread, I get one or two from, say, thread 2 and 3, and about 20 to 25 Hello, world statements from thread 0.

Why does this fail?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

像你 2024-12-19 02:16:15

我看到的一个问题是你给它一个局部变量 threadIdx 的地址。当您在循环中修改它时,线程看到的值也会更改。因此 threadIdx 值将不正确。

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

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

One issue I see is that you're giving it an address to the local variable threadIdx. When you modify it in the loop the value the thread see's is also changed. So the threadIdx value won't be correct.

In the 2nd loop you set threadIdx to 0 again and wait for threads to finish which explains why you're seeing a lot of them printing out thread 0 instead.

You can simply pass threadIdx and then interpret the void *args as an int instead (because sizeof(int) <= sizeof(void *) and is usually guaranteed on most machines) and you should get the correct output.

伪装你 2024-12-19 02:16:15

正如其他人所说,您的问题是在所有线程之间共享一个 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]);
}

As others have stated, your problem is sharing the one threadIdx variable between all the threads. One way to fix this is to create one variable per thread:

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]);
}
指尖上的星空 2024-12-19 02:16:15

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

You pass pointer to the same threadIdx variable to all threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文