C++中的线程交错模式

Posted

技术标签:

【中文标题】C++中的线程交错模式【英文标题】:Threads in C++ The interleaving pattern 【发布时间】:2019-10-08 01:23:35 【问题描述】:

在这个程序中,我试图打印我的用户名,然后创建两个线程。我希望每个线程都打印它的线程 id 并进入一个循环并定期显示一些东西。

这是我的代码

#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <string>


void task(std::string threadNum)

    std::thread::id this_id = std::this_thread::get_id();
    std::cout << threadNum << " : " << this_id << std::endl;

    for(int i=0; i<1000; i++)
        if(i == 300 or i == 600 or i == 900)
            std::cout << threadNum << " has reached step: " << i << std::endl; 
        
    



int main()

    std::cout << "Your Username Is: " << getenv("USER") << std::endl;
    std::thread t1(task, "Thread 1");
    std::thread t2(task, "Thread 2");
    t1.join();
    t2.join();


每次运行程序时我都会得到不同的输出,例如

Your Username Is: gansaikhanshur
Thread 2 : Thread 1 : 0x70000741e000
Thread 2 has reached step: 0x70000739b000300
Thread 1 has reached step: 300
Thread 2 has reached step: 600
Thread 2 has reached step: 900

Thread 1 has reached step: 600
Thread 1 has reached step: 900

Thread1 和 Thread 2 未按应有的方式显示其线程 ID。为什么我总是得到不同的结果?我是否可以让线程 1 和线程 2 显示其正确的线程 ID?

【问题讨论】:

这就是线程的作用。如果你想要线程之间的任何同步,你必须自己做 【参考方案1】:

这就是线程的工作方式——它们独立运行,它们所产生的任何副作用都可能以任何顺序交错出现。如果要确保不会发生这种情况,则需要同步。例如,如果您想确保写入cout 的行不会混淆,您可以锁定每一行输出:

std::mutex cout_lock;

void task(std::string threadNum)

    std::thread::id this_id = std::this_thread::get_id();
    
        std::lock_guard<std::mutex> lock(cout_lock);
        std::cout << threadNum << " : " << this_id << std::endl;
    

    for(int i=0; i<1000; i++)
        if(i == 300 or i == 600 or i == 900) 
            std::lock_guard<std::mutex> lock(cout_lock);
            std::cout << threadNum << " has reached step: " << i << std::endl; 
        
    

lock_guard 为您提供了一种非常简单的异常安全方式来管理锁定/解锁操作。

【讨论】:

以上是关于C++中的线程交错模式的主要内容,如果未能解决你的问题,请参考以下文章

C++ 单例模式续

C++ 线程安全的单例模式总结

C ++多线程避免函数调用期间的交错

C++ 单例模式(懒汉饿汉模式)

观察者模式的线程实现 - C++

为 32 位、64 位和 128 位生成交错位模式(morton 密钥)