【问题标题】:Posix threads problemPosix线程问题
【发布时间】:2010-12-13 09:45:50
【问题描述】:

我试图通过示例来理解 pthread。我制作了以下代码,每次运行时都会给出不同的答案!谁能解释一下这个错误吗? TIA, 斯维亚

代码在这里:

#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]$ 

【问题讨论】:

    标签: c linux posix pthreads


    【解决方案1】:

    我知道这篇文章已经过时了,但是,或者,您可以在main() 的末尾使用pthread_exit(),这样main() 将等待其所有对等线程完成,然后过早退出。

    【讨论】:

      【解决方案2】:

      好的,终于按照专家的建议添加了额外代码,现在可以正常工作了。 再次感谢大家。 :)

      for ( t = 0; t < NUM_THREADS; t++ ) {
          (void) pthread_join(threads[t], NULL);
      }
      

      【讨论】:

        【解决方案3】:

        没有错误,这就是线程的工作方式。您的主线程创建新线程,此时“准备运行”。在某个时间点(由操作系统确定),您的主线程将被挂起,而其他线程之一将运行一定时间(通常为几十毫秒)。当您的程序存在正在运行的线程时,系统将继续在线程之间切换。

        您的主线程将被中断并且其他线程之一可以打印它的 Hello World 的确切时间点将取决于操作系统调度程序决定的内容,基于您的主线程已经运行了多长时间,其他活动在系统、外部 (I/O) 事件等。

        编辑在下面包含我的评论:

        您看到 3,然后是 4,然后只有 2 个“Hello Worlds”的原因是您创建了线程,但您没有等待它们实际被调度并运行。当你的主循环结束时,程序就死了,不管你的其他线程是否有机会运行。如果您希望所有线程都完成,则需要在从 main 返回之前对每个线程执行pthread_join

        【讨论】:

        • 实际创建的线程数是3、4、4、2,但我希望所有线程都被创建,不是吗?
        • 您创建了线程,但您没有等待它们实际运行(至少一次)。当你的main 循环结束时,程序就死了,不管你的其他线程是否有机会运行。如果您希望完成所有线程,则需要在从 main 返回之前对每个线程执行 thread_join
        • pthread_create 中可能还有一个标志,可以让您告诉系统它应该等待该线程完成后再终止程序,但我不确定它叫什么...
        • 现在我解决了这个问题。谢谢。 :)
        【解决方案4】:

        我同意其他两个答案。
        还可能值得注意的是,进程在创建线程后立即退出。它将创建所有 4 个,但在程序退出之前,每个可能没有足够的时间做任何事情。

        【讨论】:

          【解决方案5】:

          根据您对其他答案的 cmets,您看不到其他线程执行的原因是因为您的 main() 函数(以及您的程序)在其他线程有机会执行之前返回。如果你在你的main() 返回之前添加一个sleep(5),你会看到它们执行。

          【讨论】:

            【解决方案6】:

            如果您指的是答案的顺序,是的,它会有所不同,因为哪个线程运行是由 Linux 调度程序决定的。

            详细说明:创建线程后,它们获得 CPU 时间的顺序取决于底层操作系统调度程序(此处为 Linux 调度程序)。这可能不会每次都一样。

            【讨论】:

            • 不。实际创建的线程数是 3、4、4、2。不明白为什么。 :(
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-04-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多