windows临界区
程序员文章站
2022-07-05 10:59:00
...
windows临界区
像下面这种编程是针对于C++语言本身的,是可以跨平台的
windows临界区和C++的mutex非常类似
现在讲讲windows下一些专用的术语,跟互斥量的关联
下面是一段用互斥量来演示的代码
class A
{
public:
//把收到的消息(玩家命令)放入到一个队列的线程
void inMsgRecvQueue()
{
for(int i = 0; i < 100000; ++i )//如果整个循环都lock,那其他线程不用玩了,循环100000次
{
cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;
//我们只给操作共享数据的内容加锁
my_mutex.lock();
msgRecvQueue.push_back(i);//假设这个数字i就是我们收到的命令,我直接弄到消息队列里边来,跑完这个循环这就等于收集了100000个玩家的命令
my_mutex.unlock();
}
return;
}
//把数据从消息队列中取出的线程
bool outMsgLULProc(int num)
{
my_mutex.lock();
if(!msgRecvQueue.empty())//空不空的判断也是属于读共享数据,所以也加锁
{
//不为空
int command = msgMsgRecvQueue.front(); //返回第一个元素,但不检查元素是否存在;我们在前面empty()已经判断过,所以问题不大
msgRecvQueue.pop_front();//拿过之后就要把第一个移除,不然一直拿都是这个
my_mutex.unlock();//这个unlock和下面的unlock不会同时执行,所以还是一个unlock与上面一个lock配对,不冲突
//要注意这种情况
///
return true;
}
my_mutex.unlock();
return false;
}
void outMsgRecvQueue()
{
int command = 0;
for(int i = 0; i < 100000; ++i )
{
bool result = outMsgLULProc(command);
if(result == true)
{
cout << "outMsgRecvQueue()执行,取出一个元素" << command << endl;
//可以考虑进行命令(数据)处理
}
else{
//消息队列为空
cout << "outMsgRecvQueue()执行,但目前消息队列中为空 " << i << endl;
}
}
cout << "end" << endl;
}
private:
std::list<int> msgRecvQueue;//容器(消息队列),专门用于代表玩家给咱们发送过来的命令(共享数据)
std::mutex my_mutex;///创建了一个互斥量
};
int main()
{
A myobja;
//创建取命令的线程
std::thread myOutnMsgObj(&A::outMsgRecvQueue, &myobja);//第二个参数是引用,这样才能保证主线程和子线程都是用同一个对象
//创建放命令线程
std::thread myInMsgObj(&A::inMsgRecvQueue, &myobja);//两个线程用同一个对象,所以他们可以消息互通
//这两个join谁先谁后问题不大
myOutnMsgObj.join();
myInMsgObj.join();
}
写windows临界区要包含一个特定的头文件 #include <windows.h>,改成用windows的临界区
//定义一个开关,如果这个开关打开就执行windows下的代码,如果关闭就执行C++11原有的代码
#define __WINDOWSJQ_
class A
{
public:
//把收到的消息(玩家命令)放入到一个队列的线程
void inMsgRecvQueue()
{
for(int i = 0; i < 100000; ++i )//如果整个循环都lock,那其他线程不用玩了,循环100000次
{
cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;
#ifdef __WINDOWSJQ_
EnterCriticalSection(&my_winsec);//进入临界区
msgRecvQueue.push_back(i);
LeaveCriticalSection(&my_winsec);//离开临界区
#else
//我们只给操作共享数据的内容加锁
my_mutex.lock();
msgRecvQueue.push_back(i);//假设这个数字i就是我们收到的命令,我直接弄到消息队列里边来,跑完这个循环这就等于收集了100000个玩家的命令
my_mutex.unlock();
#endif
}
return;
}
//把数据从消息队列中取出的线程
bool outMsgLULProc(int num)
{
#ifdef __WINDOWSJQ_
EnterCriticalSection(&my_winsec);//进入临界区
if(!msgRecvQueue.empty())//空不空的判断也是属于读共享数据,所以也加锁
{
//不为空
int command = msgMsgRecvQueue.front(); //返回第一个元素,但不检查元素是否存在;我们在前面empty()已经判断过,所以问题不大
msgRecvQueue.pop_front();//拿过之后就要把第一个移除,不然一直拿都是这个
LeaveCriticalSection(&my_winsec);//离开临界区
return true;
}
LeaveCriticalSection(&my_winsec);//离开临界区
#else
my_mutex.lock();
if(!msgRecvQueue.empty())//空不空的判断也是属于读共享数据,所以也加锁
{
//不为空
int command = msgMsgRecvQueue.front(); //返回第一个元素,但不检查元素是否存在;我们在前面empty()已经判断过,所以问题不大
msgRecvQueue.pop_front();//拿过之后就要把第一个移除,不然一直拿都是这个
my_mutex.unlock();//这个unlock和下面的unlock不会同时执行,所以还是一个unlock与上面一个lock配对,不冲突
//要注意这种情况
///
return true;
}
my_mutex.unlock();
#endif
return false;
}
void outMsgRecvQueue()
{
int command = 0;
for(int i = 0; i < 100000; ++i )
{
bool result = outMsgLULProc(command);
if(result == true)
{
cout << "outMsgRecvQueue()执行,取出一个元素" << command << endl;
//可以考虑进行命令(数据)处理
}
else{
//消息队列为空
cout << "outMsgRecvQueue()执行,但目前消息队列中为空 " << i << endl;
}
}
cout << "end" << endl;
}
A()//构造函数
{
#ifdef __WINDOWSJQ_
InitializeCriticalSection(&my_winsec);//初始化临界区,用临界区之前先要初始化
#endif
}
private:
std::list<int> msgRecvQueue;//容器(消息队列),专门用于代表玩家给咱们发送过来的命令(共享数据)
std::mutex my_mutex;///创建了一个互斥量
#ifdef __WINDOWSJQ_
CRITICAL_SECTION my_winsec;//windows中的临界区,非常类似于C++11中的mutex
#endif
};
int main()
{
A myobja;
//创建取命令的线程
std::thread myOutnMsgObj(&A::outMsgRecvQueue, &myobja);//第二个参数是引用,这样才能保证主线程和子线程都是用同一个对象
//创建放命令线程
std::thread myInMsgObj(&A::inMsgRecvQueue, &myobja);//两个线程用同一个对象,所以他们可以消息互通
//这两个join谁先谁后问题不大
myOutnMsgObj.join();
myInMsgObj.join();
}
上一篇: 安装elasticsearch
下一篇: Redis 实现单位时间内限制频率功能
推荐阅读
-
windows8 IE如何设置Cookie隐私级别图解
-
基于linux与windows平台下 如何下载android sdk源代码的方法详解
-
在Windows8上的搭建Python和Django环境
-
windows系统中Python多版本与jupyter notebook使用虚拟环境的过程
-
Windows8下安装Python的BeautifulSoup
-
Windows中使用计划任务自动执行PHP程序实例
-
Windows和Linux中php代码调试工具Xdebug的安装与配置详解
-
Typecho程序伪静态规则大全(包括Linux/Windows)
-
tcp滑动窗口和读写缓冲区
-
华为EMUI10打破Windows与安卓壁垒:实现双系统同屏操作