c++ - 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>!
我预计总会有五个“你好,世界!” 打印为该程序的输出,但我看到不同。谁能告诉我为什么?
解决方案
当主线程从main
函数返回时,它通过调用函数使进程退出exit
。根据文档,它会刷新stdout
:
所有打开的 stdio(3) 流都被刷新和关闭。
有可能因为你没有加入你的线程,主线程 flushes stdout
,而另一个线程仍在写入它。因为刷新是在std::cout
s 析构函数中完成的,所以它不需要像通常那样使用锁定(因为使用被破坏的对象是未定义的行为)。
另请注意,std::endl
两者都向流中添加了一个换行符并将其刷新。
所以想象以下顺序:
- 线程 1-4 打印它们的消息并刷新它。
- 线程 5 打印它的消息。
- 主线程退出并刷新流,这是在不持有通常的内部锁的情况下完成的
std::cout
。 - 线程 5 开始刷新
std::cout
,再次刷新与步骤 #3 中相同的消息。
推荐阅读
- bash - 替换 bash 脚本中的 ls 命令
- javascript - 从 Google 地理编码 API 返回邻居?
- python - 为什么python文件描述符'w +'在用于读取时会擦除文件的内容?
- r - 堆积条形图不正确的类别标签
- r - 如何删除数据框中特定列之前的所有列?
- php - 为什么我不能从数据库中获取所有行而不仅仅是一个条目?
- wordpress - Apache htaccess 仅重定向 root 而不更改 url root
- java - 如何将文字 JSON 字符串作为 JSON 对象返回
- javascript - 在另一个类中显示结果搜索
- pandas - 如何避免编码 if 语句两次