c++ 当调用jthread::join时,编译器如何知道要阻止哪些指令?

tf7tbtn2  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(114)

使用以下代码:

#include <iostream>
#include <thread>

using namespace std::literals;

void print(std::string msg) {
    while (true) {
        std::cout << msg << '\n';
        std::this_thread::sleep_for(3s);
    }
}

int main() {
    std::jthread t1{ print, "Hello world!" };
    std::jthread t2{ print, "Batman" };

    t1.join();
    std::cout << "Is not printed\n";
    t2.join();

    return 0;
}

在这段代码中,t2和t1同时执行,但"Is not printed"永远不会打印出来。如果join阻塞当前线程直到加入的线程结束,那么既然t1应该永远运行,那么t2.join()代码是如何调用的?对t2.join()的调用不是在主线程中吗?编译器是否有特殊的规则,它只会阻止不是调用std::jthread::join的指令,如std::cout << "Is not printed?"
编辑:当我运行这个程序时,我期望每3秒钟只打印一次“Hello World”,但由于某种原因,它也每3秒钟打印一次 bat 侠。我对这种行为感到困惑,因为我认为程序应该阻塞,直到t1完成。我知道t1t2和主线程是不同的线程。我知道应该只封锁主线,在这种情况下应该印“ bat 侠”。但是,start t2调用是在主线程中。为什么这个指令没有被阻塞,而不是std::cout << "Is not printed"

yeotifhr

yeotifhr1#

当您在main()的前两行调用t1和t2时,这些线程立即开始执行。此时,3个函数在3个线程中同时运行:t1、t2和main()。
这就是为什么你看到“hello world”和“batman”都被打印出来的原因。因为这两个线程同时执行这些函数。
您的main()函数在t1.join()上被阻塞。这是在等待t1完成执行。所以你的main()函数永远不会到达“Is not printed”行,因为它仍然在等待t1完成(而t1永远不会完成,因为你有一个无限循环。
所有join()的意思是“在这里等待,直到线程完成执行。”

相关问题