gpt4 book ai didi

c++ - 如果不使用 pthread_join(),为什么从特定线程打印两次 'cout' 语句(即使已同步)?

转载 作者:太空狗 更新时间:2023-10-29 23:01:05 25 4
gpt4 key购买 nike

#include < iostream >  
#include < pthread.h >
using namespace std;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* Func(void *)
{
pthread_mutex_lock(&mutex);
cout << "First thread execution" << endl;
pthread_mutex_unlock(&mutex);
}

int main()
{
pthread_t th1;
pthread_create(&th1, NULL, Func, NULL);
pthread_mutex_lock(&mutex);
cout << "In main thread" << endl;
pthread_mutex_lock(&mutex);
// pthread_join(th1, NULL); // Note this code is commented
return 0;
}

我在 linux fedora 22 上(也在 http://www.cpp.sh/ 上)执行了以下程序大约 20 次,在 20 次执行中我发现了以下输出:-

输出1:

In main thread  
First thread execution

输出2:

First thread execution  
In main thread

输出3:

In main thread  

输出4:

In main thread  
First thread execution
First thread execution

输出 1 到 3 是预期的,因为主线程没有等待子线程退出。两个线程(主线程和子线程)的执行顺序完全依赖于内核线程调度。

但是输出 4 很奇怪!!! 第一个线程执行被打印两次!!!

现在,如果我在取消注释代码 'pthread_join(th1, NULL)' 或添加 'pthread_exit(NULL)' 后运行程序,我不会得到奇怪的输出(即 First thread execution never printed两次)曾经,即使我运行代码 10000 次。

我向专家提出的问题是:

  1. 在没有 pthread_join/pthread_exit 的情况下,幕后发生了什么,使得 First thread execution 被打印了 2 次?

pthread_join 的职责是获取特定线程的退出代码,成功调用pthread_join 后,内核将释放该特定线程的资源。如果我不在可连接线程上调用 pthread_join 那么它会导致资源泄漏,但为什么会出现上述奇怪的行为??

我们可能会说,这是未定义的行为,但如果有专家对此提供技术解释,那就太好了。

  1. pthread_join/pthread_exit 如何防止上述奇怪的行为?由于奇怪的行为没有出现,它在这里做了什么隐藏的事情?

提前感谢专家..

最佳答案

我在类似的情况下观察到这种重复打印。当您的线程在 write 系统调用中等待执行其正常输出时,特别是在此堆栈中:

#0  0x00007ffff78f4640 in write () from /lib64/libc.so.6
#1 0x00007ffff788fb93 in _IO_file_write () from /lib64/libc.so.6
#2 0x00007ffff788fa72 in new_do_write () from /lib64/libc.so.6
#3 0x00007ffff7890e05 in _IO_do_write () from /lib64/libc.so.6
#4 0x00007ffff789114f in _IO_file_overflow () from /lib64/libc.so.6

程序正常终止,正常终止导致输出子系统刷新所有缓冲区。 stdin 上的输出缓冲区尚未标记为空闲(write 系统调用尚未返回),因此再次写出:

#0  0x00007ffff78f4640 in write () from /lib64/libc.so.6
#1 0x00007ffff788fb93 in _IO_file_write () from /lib64/libc.so.6
#2 0x00007ffff788fa72 in new_do_write () from /lib64/libc.so.6
#3 0x00007ffff7890e05 in _IO_do_write () from /lib64/libc.so.6
#4 0x00007ffff7890140 in _IO_file_sync () from /lib64/libc.so.6
#5 0x00007ffff7891f56 in _IO_default_setbuf () from /lib64/libc.so.6
#6 0x00007ffff7890179 in _IO_file_setbuf () from /lib64/libc.so.6
#7 0x00007ffff7892703 in _IO_cleanup () from /lib64/libc.so.6
#8 0x00007ffff78512f8 in __run_exit_handlers () from /lib64/libc.so.

在任何情况下,加入您的线程(如果您使用 C++ 线程,它会提醒您这样做)或以其他方式同步对输出流的访问。

关于c++ - 如果不使用 pthread_join(),为什么从特定线程打印两次 'cout' 语句(即使已同步)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31914205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com