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

标签 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

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

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上同步?

最佳答案

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

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

您在 Visual Studio 中看到类似的东西纯属巧合,不能保证,而您在 Linux 下看到其他东西的事实更有可能是关于 IO 执行方式的差异而不是线程执行方式的差异操作。

我在猜测您实际上想在这里做什么,但我怀疑您想要一个 condition_variablenotify_one。但是,您同样不应该假设它会循环。

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

--- 编辑 ---

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

关于c++ 11 线程在 linux 和 windows 上的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30434745/

相关文章:

c++ - 带有删除器的 unique_ptr

c++ - 存储结构的动态数组

c++ - 对 android_main 的 undefined reference (Android NDK - native_app_glue)

c++ - 多个相似功能的编码风格

php - PHP/Linux 中的 SNMP 陷阱

php - UTF-8贯穿始终

windows - Windows 上两个网络套接字之间的管道数据

java - 临时文件、单实例锁和进程终止 (Java)

windows - 在每个子文件夹中运行命令

linux - sudo 在 centOS 6.9 服务器上不工作