admin管理员组文章数量:1599543
// 多线程6.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include<mutex>
#include<thread>
#include<list>
using namespace std;
class A_Mutex {
public:
void inMsgRecvQueue() //把收到的消息(玩家命令)到一个队列的线程。100000次便于观察
{
for (int i = 0; i < 100000; i++)
{
unique_lock <mutex> u_lock_defer(my_mutex); //unique_lock
cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;
msgRecvQueue.push_back(i);
//my_cond.notify_one(); //尝试把wait的线程唤醒,但如果outMsgRecvQueue正在处理别的事务,而不是卡在wait()那等待被唤醒,那此时这个notify_one可能就没效果
my_cond.notify_all();
//...处理代码
//....处理其他代码
}
return;
}
bool outMsgLULProc(int &command)
{
/*
if (!msgRecvQueue.empty()) //双重锁定
{
unique_lock <mutex> u_lock(my_mutex);
if (!msgRecvQueue.empty()) //消息不为空
{
command = msgRecvQueue.front();//返回第一个元素
msgRecvQueue.pop_front();//弹出第一个元素(移除)
return true;
}
}
return false;
*/
}
void outMsgRecvQueue()//把数据从消息队列中取出的线程
{
int command = 0;
//condition_variable
while (true)
{
unique_lock <mutex> u_lock(my_mutex);
//wait()用来等一个东西
//如果第二个参数为true,那么wait()直接返回
//如果第二个参数(lambda表达式返回值是false,那么wait将解锁互斥量,并堵塞在本行)
//堵塞到什么时候为止?堵塞到其他某个线程调用notify_one()成员函数为止
//如果wait()没有第二个参数:my_cond.wait(u_lock);那么第一次调用默认条件为false(解锁互斥量,并堵塞在本行),等到被唤醒后再执行后面代码。
//将wait唤醒后: 1.wait()不断尝试重新获取互斥量锁并加锁;
// 2.wait()在获取到锁并加锁后,如果wait()有第二个参数,则判断lambda表达式(或其他函数),若为false,再次解锁互斥量,并阻塞(再次等待被notify_one唤醒)
//如果lambda表达式为true,则wait()返回,流程走下来(开始执行wait后的代码,拥有互斥量锁)
// 如果wait()没有第二个参数,则wait()返回,流程走下来(开始执行wait后的代码,拥有互斥量锁)
my_cond.wait(u_lock, [this] { //一个lambda就是一个可调用对象(函数)
if (!msgRecvQueue.empty())
return true;
return false;
});
//走到这一步,互斥锁一定被此线程锁起来了,并消息队列至少有一条数据
//处理代码
command = msgRecvQueue.front();//返回第一个元素
msgRecvQueue.pop_front();//弹出第一个元素(移除)
cout << "outMsgRecvQueue()执行,取出" << command << " thread id=" << this_thread::get_id() << endl;
u_lock.unlock(); //可提前解锁(unique_lock的灵活性)
//其他非共享数据代码
//...
}
/*
//与双重锁定配合使用
for (int i = 0; i < 100000; i++)
{
if (outMsgLULProc(command) == true)
{
cout << "outMsgRecvQueue()执行" << i << endl;
//可以对command进行数据处理
}
else
{
//消息队列为空
cout << "outMsgRecvQueue()执行,但目前消息队列为空" << i << endl;
}
}
cout << "end" << endl;
return*/
}
private:
list <int> msgRecvQueue; //容器(消息队列),专门用于代表玩家发送过来的命令
mutex my_mutex; //创建了一个互斥量(一个锁)
condition_variable my_cond; //生成一个条件对象
};
int main()
{
A_Mutex myobja;
thread myOutnMsgObj(&A_Mutex::outMsgRecvQueue, &myobja);
thread myOutnMsgObj2(&A_Mutex::outMsgRecvQueue, &myobja);
thread myInMsgObj(&A_Mutex::inMsgRecvQueue, &myobja);
myOutnMsgObj.join();
myOutnMsgObj2.join();
myInMsgObj.join();
//一:条件变量std::condition_variable、wait()、notify_one:只能通知一个线程的wait
//线程A:等待一个条件(消息队列不为空)满足
//线程B:专门往消息队列中放数据
//std::condition_variable实际上是一个类,是一个和条件相关的类(等待一个条件达成)
//这个类需要和互斥量配合工作,用的时候需要生成这个类的对象
//二:notify_all() 唤醒所有wait线程
return 0;
}
本文标签: 多线程conditionvariablenotifywait
版权声明:本文标题:多线程中的condition_variable之wait与notify(C++) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1728324281a1154229.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论