Posix线程问题

时间:2009-11-05 12:23:48

标签: c linux posix pthreads

我试图通过例子来理解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]$ 

6 个答案:

答案 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);
}