【问题标题】:why there is no output for `pthread`?为什么“pthread”没有输出?
【发布时间】:2016-06-29 06:19:58
【问题描述】:
#include <pthread.h>
#include <stdio.h>

typedef struct thread_char_para {
    char character;
    int count;
} thread_char_para;

void* char_print (void* parameter)
{
    thread_char_para* p = (thread_char_para*)parameter;
    int i;
    for (i = 0; i < p->count; ++i)
        fputc(p->character, stderr);
    return NULL;
}
int main()
{
    pthread_t thread1;
    pthread_t thread2;
    thread_char_para para1 = {'x', 30000};
    thread_char_para para2 = {'o', 30000};

    pthread_create(&thread1, NULL, char_print, &para1);
    pthread_create(&thread2, NULL, char_print, &para2);

    return 0;
}

为什么没有任何输出?

我还找到了一些阅读链接:Detached vs. Joinable POSIX threads

在这个链接中,它说pthread_join 不是必需的。所以,我想知道。

【问题讨论】:

  • 如果不使用pthread_join,程序可能会在线程运行之前退出
  • 查看您的历史记录,您也可以通过your previous question得到答案

标签: c++ c pthreads


【解决方案1】:

您需要在pthread_create() 之后调用pthread_join()pthread_exit(),否则main() 也会返回杀死生成的线程。所以没有输出会被打印出来。

【讨论】:

  • 此外,如果您从 main() 调用 pthread_exit(),它将允许生成的线程继续执行,仅终止主线程。如果您以 pthread_exit() 结束 main,则您明确表示您希望其他线程继续。
  • 当主线程被pthread_exit杀死时,拥有主线程的进程呢?它被杀了吗?
  • @BlackMamba: pthread_exit() 不会“杀死”线程,它会以明确定义的方式退出。
【解决方案2】:

作为连接两个线程的替代方法,可以将main()-线程视为任何其他线程,并使用pthread_exit() 使其退出。

这样做会阻止进程及其所有线程在main() 返回时结束。

【讨论】:

    【解决方案3】:

    您应该添加pthread_join 调用以确保您的main 函数等待其他线程完成:

    int main()
    {
        pthread_t thread1;
        pthread_t thread2;
        thread_char_para para1 = {'x', 30000};
        thread_char_para para2 = {'o', 30000};
    
        pthread_create(&thread1, NULL, char_print, &para1);
        pthread_create(&thread2, NULL, char_print, &para2);
    
        pthread_join(thread1, NULL);  // <--\ add these
        pthread_join(thread2, NULL);  // <--/   two lines.
    
        return 0;
    }
    

    为您举例说明何时可以避免 pthread_join,请查看以下代码

    #include <pthread.h>
    #include <stdio.h>
    #include <unistd.h>
    
    typedef struct thread_char_para {
        char character;
        int count;
    } thread_char_para;
    
    void* char_print (void* parameter)
    {
        thread_char_para* p = (thread_char_para*)parameter;
        int i;
    
        if (p->character == 'x')
        {
            pthread_t thread2;
            thread_char_para para2 = {'o', 30000};
            pthread_create(&thread2, NULL, char_print, &para2);
    
            for (i = 0; i < 5; ++i)
            {
                sleep(1);
            }
        }
        else
        {
            for (i = 0; i < p->count; ++i)
                fputc(p->character, stderr);
        }
        return NULL;
    }
    int main()
    {
        pthread_t thread1;
        thread_char_para para1 = {'x', 30000};
    
        pthread_create(&thread1, NULL, char_print, &para1);
    
        pthread_join(thread1, NULL);
    
        return 0;
    }
    

    如您所见,main 启动 pthread1 并等待 pthread1 完成。 pthread1 启动另一个 thread2 循环 5 秒,而 pthread2 正在执行其工作。在这种情况下,不使用pthread_join

    【讨论】:

    • stackoverflow.com/questions/3756882/…,在这个链接中,它说pthread_join 是不必要的。
    • 这里需要它,因为当 main() 返回时,应用程序将关闭。所以它必须等到线程完成执行
    • 正如@Twinkle 在主程序完成时所说,应用程序关闭并终止所有线程。
    • 此外,如果您从 main 调用 pthread_exit(),它将允许生成的线程继续执行,仅终止主线程。如果您以 pthread_exit() 结束 main,则您明确表示您希望其他线程继续。
    • @Twinkle 我想知道,哪个情况需要,哪个不需要?我很困惑。
    【解决方案4】:

    main 函数返回等效于调用exit。它杀死进程及其所有线程。因此,您的程序在线程有机会运行之前将其杀死。 pthread_create 并不意味着线程在pthread_create 内部执行,这意味着该线程将在未来的某个时间执行,而创建线程后您要做的第一件事就是杀死它们,这很可能他们还没有机会开始跑步。

    您可以通过多种方式解决此问题。正如其他人所提到的,您可以等到线程使用pthread_join 完成运行,您可以让线程向 main 指示它们是通过管道、信号量、屏障、条件变量和许多其他方式完成的。你只需要确保main 在线程完成之前不能返回,否则你很可能会在它们有机会运行之前杀死它们。

    pthread_join 没有必要,正如您所指的答案所说。在您的情况下,这只是等待线程完成运行的最简单方法。严格来说,你甚至不需要等待线程完成运行,你只需要它们向主线程表明它们已经完成了你想让它们做的事情,而线程完成是知道这一点的最简单方法他们已经开始了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-21
      • 2019-09-07
      • 2019-07-09
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多