线程之间的通信不起作用 - C++
Communication between threads not working - C++
我正在尝试编写一个简单的例子,说明生产者和消费者这两个线程之间的经典通信。创建者锁定互斥锁,生成随机字符串消息,并将它们推送到队列并释放锁。然后使用者锁定互斥锁并在屏幕上打印该数据。出于某种原因,运行代码后,我得到空白终端一段时间,然后程序终止而没有任何输出!这是我的代码:
#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
。
运行代码后,我得到空白终端一段时间,然后 程序终止,没有任何输出
由于将指针分配给 null 到std::string
,它挂起并终止:
string new_msg = NULL;
正如您在此处看到的,这将导致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
...
这段代码的状态不是很好。 如果在调试器中运行它,您可以很快找到它停止的原因,即....
string new_msg = NULL;
这是一种访问冲突,其中读取 0 (NULL
( 处的字节以获取字符串。
纠正:
string new_msg; // default value is empty.
删除它后,需要进行一些必要的更改,以使代码更接近预期行为。
new_msg = "New Random Char is "+static_cast <char> (random);
这不起作用,因为它获取字符串的地址,并向其添加 40 到 80 个字节。 它从字符串中移动到某个"随机位置"。 原始的 C 兼容性在这里受到打击,而做(我相信(意图的正确方法是......
new_msg = string("New Random Char is ") +static_cast <char> (random);
当转换为std::string
时,+ 现在表现为追加运算符。
终于在消费者...
string new_string = "producer produced " + m;
需要
new_string = "producer produced " + m;
否则,用于生成结果的变量new_string与读取队列的变量不同。
最后,在我的测试中,消费者没有跟上生产者的步伐,需要有某种形式的限制和最终条件。
- 我的神经网络不起作用 [XOR 问题]
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- C++为什么尽管我调用了void函数,它却不起作用
- 为什么在保护模式下继承升级不起作用
- 循环在计数器中不起作用
- 在其他文件中创建类时在 c++ 项目中不起作用
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 为什么二进制搜索在我的测试中不起作用
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- Bjarne Stroustrup Book - std_lib_facilities.h - 不起作用(未知类型名称)
- 为什么简单的算术减法在"if"条件下不起作用?
- 为什么Stroustup书中的has_f不起作用
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 嵌套While循环不起作用(C++问题)
- C++Matching Brackets 2解决方案不起作用
- 为什么这段代码不起作用,我该如何解决?
- 我正在开发服务器,ip作为参数传递不起作用