c++ - 子线程退出时如何通知父线程

标签 c++ linux multithreading c++11 pthreads

有人可以帮我理解子线程退出后是什么唤醒了主线程吗?我的理解是 join 调用 futex_wait ,导致主线程等待,直到子线程完成。大概有一个对 futex_wake 的调用来允许主线程恢复,但是在两个线程上运行 strace 之后,我看不到唤醒父线程的系统调用在哪里。

#include <iostream>
#include <thread>
#include <string>

void hello()
{
    std::cout <<"Hello Concurrent World" << std::endl;
}

int main ()
{
    std::thread t(hello);
    t.join();

    std::cout << "finished" << std::endl;
}

来自父线程的strace

19:37:06.206727 brk(NULL)               = 0x1380000
19:37:06.206804 brk(0x13b2000)          = 0x13b2000
19:37:06.206968 futex(0x7fcf7953005c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
19:37:06.207331 futex(0x7fcf79530068, FUTEX_WAKE_PRIVATE, 2147483647) = 0
19:37:06.207577 mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fcf780ba000
19:37:06.207726 mprotect(0x7fcf780ba000, 4096, PROT_NONE) = 0
19:37:06.207863 clone(child_stack=0x7fcf788b9fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fcf788ba9d0, tls=0x7fcf788ba700, child_tidptr=0x7fcf788ba9d0) = 10204
19:37:06.208005 futex(0x7fcf788ba9d0, FUTEX_WAIT, 10204, NULL) = 0
19:37:06.209781 write(1, "finished\n", 9) = 9
19:37:06.210021 exit_group(0)           = ?
19:37:06.210394 +++ exited with 0 +++

子线程的跟踪

19:07:09.837174 set_robust_list(0x7f123adba9e0, 24) = 0
19:07:09.837411 fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
19:07:09.837508 mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f12325ba000
19:07:09.837601 munmap(0x7f12325ba000, 27549696) = 0
19:07:09.837693 munmap(0x7f1238000000, 39559168) = 0
19:07:09.837818 mprotect(0x7f1234000000, 139264, PROT_READ|PROT_WRITE) = 0
19:07:09.837947 write(1, "Hello Concurrent World\n", 23) = 23
19:07:09.838082 madvise(0x7f123a5ba000, 8368128, MADV_DONTNEED) = 0
19:07:09.838164 exit(0)                 = ?
19:07:09.838285 +++ exited with 0 +++

当前使用 Ubuntu 16.10 编译,clang 版本 3.8.1-12,内核 4.8.0-34-generic

最佳答案

此调用:set_robust_list(0x7f123adba9e0, 24) = 0 设置一个强大的 futex,它会在线程退出时自动恢复。因此不需要系统调用来唤醒 futex。内核将在线程退出时唤醒 futex(即使线程被杀死)。

这是来自 Debianstretch 的跟踪片段,显示 fuxes“自行”恢复:

[pid 21604] 20:38:49.614788 futex(0x7f0349dbc9d0, FUTEX_WAIT, 21605, NULL <unfinished ...>
[pid 21605] 20:38:49.614851 set_robust_list(0x7f0349dbc9e0, 24) = 0
[pid 21605] 20:38:49.614948 nanosleep({tv_sec=0, tv_nsec=100000000}, NULL) = 0
[pid 21605] 20:38:49.715377 madvise(0x7f03495bc000, 8368128, MADV_DONTNEED) = 0
[pid 21605] 20:38:49.715554 exit(0)     = ?
[pid 21604] 20:38:49.715674 <... futex resumed> ) = 0
[pid 21605] 20:38:49.715701 +++ exited with 0 +++

关于c++ - 子线程退出时如何通知父线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42056524/

相关文章:

Linux 中的上下文切换

linux - 如何使用 awk、sed 打印两个特定单词之间的文本?

c++ - 尝试加入时线程崩溃

multithreading - 通过更改集合进行线程化和迭代

C++ 模板参数更改对指针的引用

c++ - C++ 中的 SAL_CALL 是什么?

c++ - 多线程程序导致段错误,使用 std::list::push_back

python - 在 Django/Gunicorn 应用程序中拥有持久(非守护进程)线程的危险?

c++ - &member 到 const 成员

c++ - 给定一个单词和一段文本,我们需要返回出现的字谜