C++ 类内线程并发

标签 c++ multithreading concurrency

我试图在一个类中运行两个并发线程,它们都使用相同的函数打印数据。使用 std::lock_guard 进行作用域锁。 问题是只有第一个线程被触发。第二个线程永远不会被调用

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

//global 
std::mutex m_printmutex;

class Class
{
public:
    Class(const std::string& s, const int& i) : m_data(s), threadName(i) { }
    ~Class() { 
        m_thread.join(); 
        m_thread2.join();
        }
    void runThread() { 
        m_thread = std::thread(&Class::print, this); 
        m_thread2 = std::thread(&Class::print,this);
    }

private:
    std::string m_data;
    std::thread m_thread;
    std::thread m_thread2;
    int threadName;
    void print()  { 
        
        while(1){
            std::lock_guard<std::mutex> lg(m_printmutex);
            std::cout << "thread # " << std::this_thread::get_id() << " "  << m_data << '\n'; 
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        }
        }
};

int main()
{
    Class c("Hello, world!",1);
    c.runThread();

}

从上面的例子可以明显看出。线程连接发生在析构函数中。

程序的输出如下:

thread # 140232348595776 Hello, world!
thread # 140232348595776 Hello, world!
thread # 140232348595776 Hello, world!
thread # 140232348595776 Hello, world!
thread # 140232348595776 Hello, world!
thread # 140232348595776 Hello, world!
thread # 140232348595776 Hello, world!
thread # 140232348595776 Hello, world!

我做错了什么?

最佳答案

       while(1){
            std::lock_guard<std::mutex> lg(m_printmutex); 
            std::cout << "thread # " << std::this_thread::get_id() << " "  << m_data << '\n'; 
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        } //mutex lock released here

互斥量在循环迭代开始时被获取。它会一直保留到迭代结束,然后立即再次抓取它,为其他线程潜入并获取互斥体留下一个非常小的窗口。

通过插入另一个代码块来从受锁保护的代码块中删除 sleep :

       while(1){
            {
                std::lock_guard<std::mutex> lg(m_printmutex); 
                std::cout << "thread # " << std::this_thread::get_id() << " "  << m_data << '\n'; 
            } // mutex lock released here
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        }

这给了另一个线程整整一秒钟的时间来获取互斥体并完成其工作。

注意:您仍然无法保证一个良好、有序的“1 线程 2 线程 1 线程 2 线程”序列。没有什么可以阻止 2 线程在 1 线程之前唤醒并获取互斥锁,反之亦然。如果您想要完美的排序,请查看 std::condition_variable

关于C++ 类内线程并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76150930/

相关文章:

java - 如何让 android 使用我的 QtActivity 子类而不是原来的 QtActivity?

c++ - 如何用 C++ 编写 "meta if else if.."?

c++ - 当单个线程获取同一互斥锁的2个unique_lock时,unique_lock是什么意思?

c++ - 任意字符串数组的加倍

c++ - 我应该在 v8::External 中手动删除指针吗?

java - 在 ExecutorService 的提交和 ExecutorService 的执行之间进行选择

c - 父级在 pthread_create 之后获取其子级 id 的有效方法?

python - python有没有比较和交换操作

java - 有没有另一种方法可以使用 CAS 操作在 Java 中编写同步块(synchronized block)?

java:由 ReentrantLock 行为指示的线程行为