微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

多线程中的 cout 无锁 C++20

如何解决多线程中的 cout 无锁 C++20

我用 C++20 编写。这是一个非常简单的程序,它要求三个线程打印一些字符串。例如,我们要求线程 1 打印 "This is thread1",线程 2 打印 "This is thread2",线程 3 打印 "This is thread3"

然而,我注意到在传递给线程的 printThread 函数中,如果我们不使用锁,我们可以获得线程之间混合的打印结果。例如This is This thread2 is thread3。我想避免这种干预,所以我用 mutex 编写了我的代码

#include <iostream>
#include <string.h>
#include <thread>
#include <mutex>
using namespace std;


mutex m_screen;
void printCnt()
{   
    lock_guard guard(m_screen);
    cout << "Func Start" << endl;
    // Fetch the thread ID of the thread which is executing this function
    thread::id threadID = this_thread::get_id();
    
    cout << "Thread [" << threadID << "] has been called " endl;
    
    
}

// g++ foo.cpp =pthread

int main(){
    thread t1(printCnt);
    thread t2(printCnt);
    thread t3(printCnt);

    t1.join();
    t2.join();
    t3.join();

    cout << "done" << endl;
    
}

不知道有没有什么办法可以达到类似互斥锁的效果,但是没有锁

解决方法

总的来说,这篇文章总结了评论中的想法(带有示例),并添加了 1 个新方法

正如 Dean Johnson 在评论中提到的,执行此操作的标准方法是 std::osyncstream 函数,然后您的代码将如下所示

void printCnt()
{   
    cout << "Func Start" << endl;
    // Fetch the thread ID of the thread which is executing this function
    thread::id threadID = this_thread::get_id();
    
    osyncstream(cout) << "Thread [" << threadID << "] has been called " endl;   
}

您还可以首先生成一个包含您的输出的字符串(如 1201ProgramAlarm 所述),然后立即输出整个字符串。这可以使用 std::stringstreamstd::format 来实现。结果,代码看起来像这样

void printCnt()
{   
    cout << "Func Start" << endl;
    // Fetch the thread ID of the thread which is executing this function
    thread::id threadID = this_thread::get_id();
    
    // stringstream ss;
    // ss << "Thread [" << threadID << "] has been called\n";
    // string output = ss.str(); 

    string output = format("Thread [{}] has been called\n","world");//or use commented variant above

    cout << output;   
}

如果你被允许使用 C 风格的函数,你可能想使用 printf(通常是格式化程序 + 打印机,但据我所知 doesn't know how to print std::thread::id

void printCnt()
{   
    cout << "Func Start" << endl;
    
    static int x = 0;
    x++;
    
    printf("Thread [%d] has been called\n",x); 
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。