首页 > 解决方案 > Pthread 行为 C++

问题描述

我尝试了一个基本的 pthreads/mutex 程序:

#include<iostream>
#include<pthread.h>

using namespace std;

pthread_mutex_t mutex;

void* PrintHello(void *t)
{
    int i = reinterpret_cast<int>(t);
    pthread_mutex_lock(&mutex);
    cout<<"Hello, World thread <"<<i<<">!"<<endl;
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
}

int main()
{
    pthread_t threadId[5];
    pthread_mutex_init(&mutex, NULL);

    for(int i = 0; i < 5; i ++)
    {
        int rc = pthread_create(&threadId[i], NULL, PrintHello, reinterpret_cast<void *>(i + 1));
    }

    return 0;
}

我得到以下输出:

执行1:

Hello, World thread <1>!
Hello, World thread <2>!
Hello, World thread <3>!
Hello, World thread <4>!
Hello, World thread <4>!
Hello, World thread <5>!

执行2:

Hello, World thread <1>!
Hello, World thread <2>!
Hello, World thread <3>!
Hello, World thread <4>!
Hello, World thread <5>!
Hello, World thread <5>!

我预计总会有五个“你好,世界!” 打印为该程序的输出,但我看到不同。谁能告诉我为什么?

标签: c++pthreadsmutex

解决方案


当主线程从main函数返回时,它通过调用函数使进程退出exit。根据文档,它会刷新stdout

所有打开的 stdio(3) 流都被刷新和关闭。

有可能因为你没有加入你的线程,主线程 flushes stdout,而另一个线程仍在写入它。因为刷新是在std::couts 析构函数中完成的,所以它不需要像通常那样使用锁定(因为使用被破坏的对象是未定义的行为)。

另请注意,std::endl两者都向流中添加了一个换行符并将其刷新。

所以想象以下顺序:

  1. 线程 1-4 打印它们的消息并刷新它。
  2. 线程 5 打印它的消息。
  3. 主线程退出并刷新流,这是在不持有通常的内部锁的情况下完成的std::cout
  4. 线程 5 开始刷新std::cout,再次刷新与步骤 #3 中相同的消息。

推荐阅读