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