为什么在此示例中 pthread_join 没有正确关闭线程数组?
我正在尝试自学 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我看到的一个问题是你给它一个局部变量 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.
正如其他人所说,您的问题是在所有线程之间共享一个
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:您将指向同一
threadIdx
变量的指针传递给所有线程。You pass pointer to the same
threadIdx
variable to all threads.