我试图通过例子来理解pthreads。我制作了以下代码,每次运行时都会给出不同的答案!有谁能解释这个bug吗? TIA, Sviiya
代码在这里:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 4
struct thread_data {
int thread_id;
int sum;
};
struct thread_data thread_data_array[NUM_THREADS];
void *PrintHello(void *threadarg)
{
struct thread_data *my_data;
int taskid;
int sum;
my_data = (struct thread_data *) threadarg;
taskid = my_data->thread_id;
sum = my_data->sum;
printf("Hello World! It's me, thread #%d\n", taskid);
return my_data;
}
int main ()
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
int sum=0;
for (t=0; t < NUM_THREADS; t++) {
printf("Hi! %ld\n", t);
threads[t] = t;
thread_data_array[t].thread_id = t;
thread_data_array[t].sum = sum;
rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &thread_data_array[t]);
}
return 0;
}
输出在这里:
[user@office tmp]$ ./a.out
Hi! 0
Hi! 1
Hello World! It's me, thread #0
Hello World! It's me, thread #1
Hi! 2
Hi! 3
Hello World! It's me, thread #2
[user@office tmp]$ ./a.out
Hi! 0
Hi! 1
Hello World! It's me, thread #0
Hello World! It's me, thread #1
Hi! 2
Hi! 3
Hello World! It's me, thread #2
Hello World! It's me, thread #3
[user@office tmp]$ ./a.out
Hi! 0
Hello World! It's me, thread #0
Hi! 1
Hello World! It's me, thread #1
Hi! 2
Hello World! It's me, thread #2
Hi! 3
Hello World! It's me, thread #3
[user@office tmp]$ ./a.out
Hi! 0
Hi! 1
Hello World! It's me, thread #0
Hi! 2
Hi! 3
Hello World! It's me, thread #3
[user@office tmp]$
答案 0 :(得分:4)
没有错误,这只是线程的工作方式。您的主线程创建新线程,此时“准备运行”。在某个时间点(由操作系统确定),您的主线程将被挂起,其他线程之一将运行一段时间(通常为几十毫秒)。当程序存在运行线程时,系统将在线程之间保持切换。
主线程将被中断并且其他线程之一可以打印它的Hello World的确切时间点将取决于OS调度程序决定的内容,具体取决于主线程已经运行了多长时间,其他活动在系统,外部(I / O)事件等
编辑以包含我的评论:
你看到3,然后是4,然后只有2个“Hello Worlds”的原因是你创建了线程,但是你没有等到它们实际上被安排和运行。当你的主循环结束时,无论你的其他线程是否有机会运行,程序都会死机。如果你想完成所有的线程,你需要在每个线程上执行pthread_join
,然后才能从main返回。
答案 1 :(得分:1)
如果你的意思是答案的顺序,是的,它会有所不同,因为哪个线程运行由Linux调度程序决定。
详细说明:创建线程后,它们获得CPU时间的顺序取决于底层的OS调度程序(此处为Linux调度程序)。这可能每次都不一样。
答案 2 :(得分:1)
根据您对其他答案的评论,您没有看到其他线程正在执行的原因是因为您的main()
函数(以及您的程序)在其他线程有机会执行之前返回。如果您在sleep(5)
返回之前放置main()
,则会看到它们已执行。
答案 3 :(得分:1)
我发现这篇文章很旧,但是,您可以在pthread_exit()
结束时使用main()
,以便main()
等待所有对等线程完成后再退出过早。
答案 4 :(得分:0)
我同意其他两个答案。
也值得注意的是,该过程在创建线程后立即退出。它将创建所有4个,但在程序退出之前,每个都可能没有足够的时间做任何事情。
答案 5 :(得分:0)
好的,最后根据专家的建议添加了extracode,现在工作正常。 再次感谢所有人。 :)
for ( t = 0; t < NUM_THREADS; t++ ) {
(void) pthread_join(threads[t], NULL);
}