c ++ 11在linux和windows上线程化不同的行为

时间:2015-05-25 09:07:59

标签: c++ linux windows multithreading c++11

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mx;
void some_function()
{
    while(1)
    {
        std::lock_guard<std::mutex> mx_guard(mx);
        std::cout << "some_function()\n";
    }
}

void some_other_function()
{
    while(1)
    {
        std::lock_guard<std::mutex> mx_guard(mx);
        std::cout << "some_other_function\n";
    }
}

int main()
{
    std::thread t1(some_function);
    std::thread t2 = std::move(t1); //t2 will be joined

    t1 = std::thread(some_other_function);

    if(t2.joinable())
    {
        std::cout << "t2 is joinable()\n";
        t2.join(); //calling join for t1
    }
    if(t1.joinable())
    {
        std::cout << "t1 is joinable()\n";
        t1.join();
    }
    return 0;
}

我在Windows和Linux上有这个程序的不同输出。在使用visual studio 13编译器的Windows上,我得到以下输出。

some_function()
some_other_function
some_function()
some_other_function
some_function()
some_other_function
some_function()
some_other_function
some_function()
some_other_function
some_function()
some_other_function

但是在linux上使用gcc输出是不同的

some_function()
some_function()
some_function()
some_function()
some_function()
some_function()
some_function()
some_other_function
some_other_function
some_other_function
some_other_function
some_other_function
some_other_function
some_other_function

在Windows上,两个线程一个接一个地打印,但在linux上它的行为并不相同。在linux上使用mutex不会同步。如何在linux上同步?

1 个答案:

答案 0 :(得分:3)

mutex只是一个锁,用于阻止对共享资源的并发访问,在本例中为std :: cout。在这两种情况下,一次只有一个线程写入std::cout。虽然在某些情况下解锁互斥锁可能会导致唤醒另一个任务,但除非您自己负责操作系统/调度程序代码,否则这不是您应该期望或依赖的。

互斥锁 限制对std :: cout的访问:如果你在没有锁定防护的情况下运行相同的代码,你可能会在一个操作系统或另一个操作系统上看到乱码/混合输出

您在Visual Studio中看到类似内容的事实纯属巧合并且无法保证,而您在Linux下看到其他内容的事实更可能是关于IO执行方式的差异。线程如何运作。

我猜测你在这里尝试做什么,但我怀疑你想要一个condition_variablenotify_one。但是,你再也不应该认为它会循环使用。

此外,joinable()测试线程是否正在运行,join()等待它们停止,但由于你的线程处于永久循环中,对join()的第一次调用将永远挂起

---编辑---

当我使用/ O2在Visual Studio 2015下运行代码时,我得到的报告输出与您报告的相同。