c++ - 线程之间的通信不起作用 - C++

标签 c++ multithreading mutex

我正在尝试编写一个简单的例子来说明两个线程(生产者和消费者)之间的经典通信。生产者锁定互斥锁,生成随机字符串消息并将它们插入队列并释放锁。然后消费者锁定互斥锁并在屏幕上打印该数据。出于某种原因,在运行代码后,我有时会得到空白终端,然后程序终止而没有任何输出!这是我的代码:

#include <iostream>
#include <stdlib.h>
#include <thread>
#include <mutex>
#include <queue>
#include <random>
#include <string>
#include <cstdlib>

using namespace std;

static mutex mmutex;
static condition_variable mcond;
static queue <string> mqueue;

void consumer() {
    while (true) {
        unique_lock<mutex> lck{mmutex};
        mcond.wait(lck);
        string new_string = "producer has not produced yet ";
        string m = "";
        if (!mqueue.empty()) {
            m = mqueue.front();
            mqueue.pop();
            string new_string = "producer produced " + m;
        }   
        cout << new_string << endl;
        lck.unlock();
    }
}

void producer() {
    while (true) {
        string new_msg = NULL;
        unique_lock<mutex> lck{mmutex};
        int random = rand() % 40 + 40;
        new_msg = "New Random Char is "+static_cast <char> (random);
        mqueue.push(new_msg);
        mcond.notify_one();
    }
}




int main() {

    thread t1{ producer };
    thread t2{ consumer };


    t1.join();
    t2.join();
    cout << "exiting"<<endl;
    system("PAUSE");
    exit(0);
}

最佳答案

总的来说,您的同步方案很好。除此之外,该代码有一个运行时错误、一些使用 std::string 的意外后果和一个不必要的(并且可能误导读者)调用:unlock( )std::unique_ptr 上。

after running the code I get blank terminal for some times and then program terminates without any outputs

由于 将指向 null 的指针分配给 std::string,它挂起并终止:

string new_msg = NULL;

尽你所能 see here ,这将导致 std::string 实例尝试访问这个零地址:(

其次,您无法通过字符串文字char 连接起来来获得您想要的结果,如以下行所示:

string new_string = "producer produced " + m;

new_msg = "New Random Char is "+static_cast <char> (random);

这里是您的线程过程的一个有效的、稍微更好的编写版本,您可以在其中看到各种有效的方法来初始化和分配给 std::string 以获得您想要的。再次注意 删除 lck.unlock(); 因为 std::unique_lock 是一个 RAII对象,它将在 while 范围退出时按原样释放 mutex:

void consumer() {
    while (true) {
        unique_lock<mutex> lck{ mmutex };
        mcond.wait(lck);
        string new_string;
        if (!mqueue.empty()) {
            string m = mqueue.front();
            mqueue.pop();
            new_string = string("producer produced ") + m;
        }
        else
        {
            new_string = "producer has not produced yet ";
        }
        cout << new_string << endl;
        //lck.unlock(); // <--- Not the intended usage of `unique_lock`
    }
}

void producer() {
    while (true) {
        string new_msg("New Random Char is ");
        unique_lock<mutex> lck{ mmutex };
        int random = rand() % 40 + 40;
        new_msg += static_cast<char>(random);
        mqueue.push(new_msg);
        mcond.notify_one();
    }
}

输出:

producer produced New Random Char is F
producer produced New Random Char is =
producer produced New Random Char is K
producer produced New Random Char is N
producer produced New Random Char is *
producer produced New Random Char is :
producer produced New Random Char is 3
producer produced New Random Char is O
producer produced New Random Char is @
producer produced New Random Char is E
producer produced New Random Char is I
...

关于c++ - 线程之间的通信不起作用 - C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52379927/

相关文章:

c++ - 使用窗口而不是对话框的优势

multithreading - vxworks 任务如何让所有其他较低优先级的任务在单个多任务循环中运行?

linux - Linux 驱动程序上下文中的微秒延迟和自旋锁

c - 当只有一个线程写入共享变量时,我需要锁吗?

c++ - 跨各种线程的unique_lock

c++ - 当不是 waitForFinished() 时,QProcess 不发出信号

c++ - 创建大小为 m x n 的类 MAT

c++ - 我可以从 automake/autoconf 中提取 libtool 配置以供单独使用吗?

java - 在单例中创建线程

c - Linux 内核线程