網站首頁 編程語言 正文
保護共享數據,操作時,用代碼把共享數據鎖住、操作數據、解鎖
其他想操作共享數據的線程必須等待解鎖、鎖定住、操作、解鎖
互斥量的基本概念
- 互斥量是個類對象,理解成一把鎖,多個線程嘗試使用lock()成員函數來枷鎖這個鎖,是有一個線程可以鎖成功,成功的標志是返回
- 如果沒有鎖成功,那么流程卡在lock這里不斷嘗試去鎖
互斥量的使用
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <list>
#include <mutex>
using namespace std;
class A {
public:
//把收到的消息(玩家命令) 入到一個隊列的線程
void inMsgRecvQueue()
{
for (int i = 0; i < 1000; i++) {
cout << "inMsgRecvQueue執行,插入一個元素" << i << endl;
my_mutex.lock();
msgRecvQueue.push_back(i);//假設這個數字就是收到的命令
my_mutex.unlock();
}
}
int mesg_lock_func(void)
{
int ret = 0;
my_mutex.lock();
if (!msgRecvQueue.empty()) {
ret = msgRecvQueue.front();//讀頭部元素
msgRecvQueue.pop_front();//移除頭部元素
//處理數據
//cout << "接收到命令,處理命令" << ret << endl;
}
my_mutex.unlock();
return ret;
}
void outMsgRecvQueue()
{
int cmd = 0;
for (int i = 0; i < 1000; i++)
{
cmd = mesg_lock_func();
if (cmd) {
cout << "接收到命令,處理命令" << cmd << endl;
}
else
{
cout << "outMsgRecvQueue執行,但目前消息隊列為空" << i << endl;
}
}
}
private:
list<int> msgRecvQueue; //容器,專門用于代表玩家給咱們發送過來的命令
mutex my_mutex;
};
lock_guard類模板
為什么此處只有一句 lock_guard sbguard(my_mutex);函數即可 不出問題
lock_guard原理:
lock_guard創建 sbguard(my_mutex);對象,會有構造函數,在構造函數中進行了my_mutex.lock
在函數執行結束后,局部對象會釋放,執行析構函數的時候會執行my_mutex.unlock
int mesg_lock_func(void)
{
int ret = 0;
//my_mutex.lock();
lock_guard<mutex> sbguard(my_mutex);
if (!msgRecvQueue.empty()) {
ret = msgRecvQueue.front();//讀頭部元素
msgRecvQueue.pop_front();//移除頭部元素
//處理數據
//cout << "接收到命令,處理命令" << ret << endl;
}
//my_mutex.unlock();
return ret;
}
死鎖
死鎖的條件:
兩個線程同時 鎖住 兩把鎖, A線程先鎖 鎖1,后鎖 鎖2;B線程先鎖 鎖2,后鎖 鎖1,就會發生死鎖
class A {
public:
//把收到的消息(玩家命令) 入到一個隊列的線程
void inMsgRecvQueue()
{
for (int i = 0; i < 10000; i++) {
cout << "inMsgRecvQueue執行,插入一個元素" << i << endl;
my_mutex1.lock();
my_mutex2.lock();
msgRecvQueue.push_back(i);//假設這個數字就是收到的命令
my_mutex2.unlock();
my_mutex1.unlock();
}
}
int mesg_lock_func(void)
{
int ret = 0;
my_mutex2.lock();
my_mutex1.lock();
//lock_guard<mutex> sbguard(my_mutex);
if (!msgRecvQueue.empty()) {
ret = msgRecvQueue.front();//讀頭部元素
msgRecvQueue.pop_front();//移除頭部元素
//處理數據
//cout << "接收到命令,處理命令" << ret << endl;
}
my_mutex1.unlock();
my_mutex2.unlock();
return ret;
}
void outMsgRecvQueue()
{
int cmd = 0;
for (int i = 0; i < 10000; i++)
{
cmd = mesg_lock_func();
if (cmd) {
cout << "接收到命令,處理命令" << cmd << endl;
}
else
{
cout << "outMsgRecvQueue執行,但目前消息隊列為空" << i << endl;
}
}
}
private:
list<int> msgRecvQueue; //容器,專門用于代表玩家給咱們發送過來的命令
mutex my_mutex1;
mutex my_mutex2;
};
防止死鎖的條件:
兩個鎖的 鎖的順序必須相同
lock(mutex1, mutex2);
lock_guard sbguard1(my_mutex1,adopt_lock);’
lock與lock_guard的使用
int mesg_lock_func(void)
{
int ret = 0;
lock(my_mutex1, my_mutex2);
lock_guard<mutex> sbguard1(my_mutex1, adopt_lock);
lock_guard<mutex> sbguard2(my_mutex2, adopt_lock);
//lock_guard<mutex> sbguard(my_mutex);
if (!msgRecvQueue.empty()) {
ret = msgRecvQueue.front();//讀頭部元素
msgRecvQueue.pop_front();//移除頭部元素
//處理數據
//cout << "接收到命令,處理命令" << ret << endl;
}
return ret;
}
原文鏈接:https://blog.csdn.net/zzsxyl/article/details/125555684
相關推薦
- 2022-03-17 分布式數據存儲系統的三要素_數據庫其它
- 2022-04-26 Python中Enum使用的幾點注意事項_python
- 2022-05-08 ASP.NET中Web?API解決跨域問題_實用技巧
- 2023-02-17 Python的OptionParser模塊示例教程_python
- 2024-01-29 在springboot多數據源項目中創建多個事務(解決@Transactional影響切換數據源問題
- 2023-03-13 使用webpack配置react-hot-loader熱加載局部更新_React
- 2023-02-02 一文教你利用Python制作一個生日提醒_python
- 2022-05-13 C語言中判斷素數(求素數)的思路與方法實例_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支