当前位置: 首页 > news >正文

C++\MFC锁lock从专家到小白

C++ mutex

# include <mutex>
std::mutex m_lock;
void CMainWnd::function()
{
    std::lock_guard<std::mutex> lock(m_lock);
    ...
}
  1. 仅限同一进程内
  2. 阻塞等待:当线程 A 持有锁时,线程 B 尝试获取同一互斥锁时,会进入阻塞状态(除非使用 try_lock),直到线程 A 释放锁。
  3. 独占性:std::mutex 是独占锁,同一时间只允许一个线程持有锁。
  4. 不可重入:同一线程重复获取 std::mutex 会导致死锁(需使用 std::recursive_mutex 实现可重入)。

RALL

std::lock_guard是一个用于管理互斥锁的RAII(资源获取即初始化)类。
RAII:在对象构造时获取资源,在对象析构时释放资源。
当创建一个lock_guard对象时,它会自动锁定给定的互斥量m_lock,而当这个lock_guard对象离开其作用域时,会自动释放互斥量。在离开作用域时自动释放锁,无需手动干预,保证了资源管理的安全性和简洁性。这种设计避免了忘记释放锁或异常导致的死锁问题,是C++中管理互斥锁的首选方式。

释放锁的时机和方式

​1. 作用域结束释放。
2. 异常安全。若临界区代码抛出异常,栈展开会触发 lock_guard 析构,确保锁被释放,避免死锁。
3. 显式作用域控制。通过代码块{}可提前释放锁,缩短持有锁的时间。
4. 多返回点保证。函数中有多个 return 语句,lock_guard 也会在函数返回前析构,确保锁被释放。

try_lock()

try_lock_for(timeout)

MFC

CCriticalSection

CCriticalSection m_cs;
void ThreadSafeFunction() 
{
    m_cs.Lock();    // 阻塞等待锁
    // 临界区操作(访问共享资源)
    m_cs.Unlock();  // 必须手动解锁!
}

允许同一线程多次调用 Lock() 方法(即支持递归锁/可重入锁)。
CCriticalSection 内部维护一个计数器,记录当前线程持有锁的次数。
只有当计数器归零时,锁才会真正释放,允许其他线程获取。

CMutex

必须手动解锁。

CMutex  m_Mutex;
void CMainWnd::function()
{
	m_Mutex.Lock();
	// 临界区操作
	m_Mutex.Unlock();
}

使用 CSingleLock 自动管理

析构时自动调用 Unlock()。

CSingleLock lock(&mutex);
lock.Lock();
if (lock.IsLocked()) 
{
    // 临界区操作
} //析构时自动调用 Unlock()

非阻塞模式

CSingleLock lock(&mutex);
if (lock.Lock(0)) {  // 参数为超时时间(毫秒),0 表示立即返回
    // 成功获取锁
} else {
    // 锁被占用,执行其他逻辑
}

跨进程同步:命名互斥体

// 进程 A
CMutex mutexA(FALSE, _T("Global\\MyMutex"));  // 注意 "Global\\" 前缀确保系统级可见性
CSingleLock lockA(&mutexA);
lockA.Lock();
// 操作共享资源...

// 进程 B
CMutex mutexB(FALSE, _T("Global\\MyMutex"));
CSingleLock lockB(&mutexB);
lockB.Lock();
// 操作同一共享资源...

相关文章:

  • 基于银河麒麟桌面服务器操作系统的 DeepSeek本地化部署方法【详细自用版】
  • Etcd用的是Raft算法
  • Linux上位机开发实践(超越MPP去开发产品)
  • 青少年编程与数学 02-014 高中数学知识点 07课题、专业相关性分析
  • Blender模型导入虚幻引擎设置
  • 静态住宅IP的应用、设置及好处
  • 开发相关的一些网址收藏(持续更新中)
  • [原创](Modern C++)现代C++的关键性概念: 如何正确地返回函数指针?
  • 【Linux高级IO(一)】理解五种IO模型
  • MySQL篇(一):慢查询定位及索引、B树相关知识详解
  • springboot整合Thymeleaf web开发出现Whitelabel Error Page
  • R语言——获取数据1
  • Python Websockets库深度解析:构建高效的实时Web应用
  • MySQL和Oracle常见语法差异详解
  • 【Easylive】AppInterceptor和WebAppConfigurer 基于 Token 的请求拦截验证机制
  • 高级java每日一道面试题-2025年3月20日-虚拟化操作系统篇[Docker篇]-如何控制docker容器的启动顺序?
  • 【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(12)
  • 文件系统--软硬链接/动静态库
  • C# 窗体应用(.FET Framework ) 打开文件操作
  • 万字解析Spring简易版实现方案!
  • 世界羽联主席巴达玛:中国组织赛事的能力无与伦比
  • 以总理:在加沙地带扩大的军事行动将是“高强度”的
  • 争抢入境消费红利,哪些城市有潜力?
  • 经济日报头版评论:矢志奋斗筑梦青春中国
  • 英伟达:美国无法操纵监管机构在AI领域取胜,美企应专注创新而不是编造荒诞谣言
  • 纽约大都会博物馆展“萨金特与巴黎”:从艺术生到明星画家