寻找 std::join 行为的澄清
Looking for clarification of std::join behavior
我一直在学习更多关于多线程和锁定的知识,这让我想到了 http://www.cplusplus.com/reference/thread/thread/join/提供的基本示例
该页面提供的基本解释是:
该函数在线程执行完成后返回。
好的,听起来有点像我们启动了一个线程,当我们启动的线程完成时,我们将恢复调用线程。
下面是来自站点的一些示例代码,我已向其添加了一个 print 语句。
#include <iostream>
#include <thread>
#include <mutex>
#include <unistd.h>
std::mutex mtx;
void print_block (int n, char c) {
mtx.lock();
for (int i = 0; i < n; i++)
{
std::cout << c;
}
std::cout << std::endl ;
mtx.unlock();
return;
}
int main()
{
std::thread th1(print_block, 50, '*');
std::thread th2(print_block, 60, '$');
th1.join();
//my print statement
std::cout << "In between thread joins" << std::endl;
th2.join();
return 0;
}
根据我看到的联接描述,我希望输出为:
****
在螺纹连接之间
$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
我的逻辑是:
主线程调用 th1.join,因此主线程停止执行,直到 th1.join 完成。
th1 执行在打印出星星后完成,然后我的 print 语句执行
TH2 执行开始和结束
实际上情况并非如此,th2 可以在 th1 之前执行,我的 print 语句通常排在最后。 连接实际上对主线程有什么作用? 它似乎并没有像我一直在线阅读那样真正阻止它。
无论如何,我的解释毫无意义,因为它似乎与单线程进程相同。 帮助!
TLDR;
当你调用加入时,到底会发生什么? 新线程开始,但主线程会发生什么? 如果主线程确实阻塞,为什么我的例子不是这种情况?
谢谢
编辑:
我想我明白了。 出于某种原因,我认为 th1 在调用 join 时开始执行。 th1 在调用构造函数时开始执行。 Join 将阻塞主线程,直到 th1 在开始执行后完成。 谢谢大家!
这个例子很糟糕(原因如下);
当你调用加入时,到底会发生什么?新线程开始,但是 主线程会发生什么变化?如果主线程确实阻塞,为什么 我的例子不是这样吗?
th1.join()
将阻止当前线程(在本例中为运行函数main()
的执行线程)的执行,直到th1
表示的执行线程完成并返回。
现在,这与th2
是否在th1
之前完成无关 - (不能保证线程th1
进入函数并在线程th2
之前选择锁)。这种方法只是说,"在th1
完成之前不要继续"。
所以,是的,th2
可能会在th1
之前完成,但是
std::cout << "In between thread joins" << std::endl;
在th1
完成之前永远不会被执行。
不好的例子:
- 关于异常安全。更喜欢
std::lock_guard
.从今以后,请首选使用cppreference.com。 int main()
中的std::cout ...
不受保护,是的,std::cout
没有种族,但在被多个线程使用时不能交错字符输出- 如果您需要某些函数之间的相对排序,则可能不是您想要使用的
std::thread
。而且,更喜欢更高的抽象,例如std::async
. - 从代码上讲,即使
int main()
中的std::cout ...
被认为是不可分割的交易,将th1.join()
放在它之前,th2.join()
之后也只是一种欺骗。我会让连接在代码上相互跟随。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- 在std::thread中,joinable()然后join()线程安全吗
- std::future::get()或std::future::wait()是std::thread::join()的替
- c++17 std::thread join() : 没有这样的进程
- std::thread::join() 可以从非父线程调用吗?
- 寻找 std::join 行为的澄清
- 在我调用join()之前,std ::线程运行
- std::thread::join 在析构函数中挂起
- 将字符串的向量连接到std::ostream(类似于boost::Join)
- 执行std::thread::join()时的SIGINT
- std::thread.join() deadlock
- std::thread.join()和SFML不兼容