【学习笔记】Windows 下线程同步之互斥锁

news2024/11/17 9:27:18

目录

  • 前言
  • 环境
  • 简介
  • 相关函数
    • CreateMutex
  • Wait 函数
    • ReleaseMutex
    • CloseHandle
  • 其他
    • 互斥锁的名字
    • 未命名互斥锁的同步
    • 互斥锁的意外终止
    • 临界区对象
  • 参考

前言

  1. 本文所涉及的同步主要描述在 Windows 环境下的机制,和 Linux 中的同步机制有一定的联系,但注意并不完全相同。类似于,Windows 和 Linux 按照自己的方式实现了操作系统中同步机制的概念
  2. 本文记录的是 Windows 下的互斥锁同步机制,但在 Windows 的同步机制中,其中很多的概念和逻辑同样适用于事件(Event),信号量,计时器等其他同步机制

环境

  1. OS:win
  2. IDE:Visual Studio 2015

简介

  • 简介:互斥锁是一种同步对象,当没有任何线程拥有互斥锁时,互斥锁处于有信号(signaled)状态,当互斥锁被某个线程拥有,则它处于无信号状态(nonsignaled)。

    顾名思义,互斥锁就是一种为了达到访问共享资源而互斥目的的锁。比如生活中,公共厕所就是一种共享资源,公厕一次只能有一个人使用,使用者在使用的时候就会关门上锁,使用完之后需要开门释放锁。对于每个使用者来说,这个锁一次只能被一个人占有

  • 特点

    • 任何一个互斥锁,一次只能被一个线程拥有
    • 可以跨进程使用,即进程间同步
  • 适用场景:同步一些共享资源,比如共享内存(shared memory)

相关函数

CreateMutex

  1. 作用:创建或打开命名或未命名的互斥锁对象。如果某互斥锁已经被创建,当再次使用 CreateMutex 操做该互斥锁,实际的操作等效于 OpenMutex,但通过 GetLastError 会返回 ERROR_ALREADY_EXISTS 标识
  2. 语法
HANDLE CreateMutexA(
  [in, optional] LPSECURITY_ATTRIBUTES lpMutexAttributes,
  [in]           BOOL                  bInitialOwner,
  [in, optional] LPCSTR                lpName
);
  1. 参数
    1. lpMutexAttributes,为 NULL 时,句柄不能被子进程继承
    2. bInitialOwner,为 true 时,创建该互斥锁的线程获取该互斥锁
    3. lpName,互斥锁的名字,为 NULL 时,为未命名互斥锁,关于未命名互斥锁如何传递见下方“未命名互斥锁的同步”

Wait 函数

  1. Wait 函数是一系列提供类似功能的等待函数(如 WaitForMultipleObjects),该函数的作用是请求某个互斥锁的使用权,若没有获取到,则阻塞
  2. 等待函数的返回值表明等待函数因为某些原因返回,而不是正常的互斥锁信号转换
  3. 多个线程等待互斥锁时,只有一个线程会被随机选择获取互斥锁

ReleaseMutex

  1. 作用:释放控制权,释放后,互斥锁变为有信号状态
  2. 语法
BOOL ReleaseMutex(
  [in] HANDLE hMutex
);
  1. 参数:hMutex 是要释放的互斥锁句柄

CloseHandle

  1. 作用:关闭句柄,本文中即关闭互斥锁
    【注】除了使用 CloseHandle 手动关闭句柄外,当某个进程终止后,也会自动关闭句柄
    【注】CloseHandle 关闭当前线程中使用的句柄,但如果还有其他线程拥有该句柄,那么句柄对象并未真正关闭,只有当最后一个该对象被关闭,句柄才会真正关闭
    在这里插入图片描述

如图,只有当所有句柄均被关闭,互斥锁对象才会自动关闭

其他

互斥锁的名字

特别注意的是,互斥锁的名字和其他同步对象(如,事件,信号量)的名字位于相同的命名空间,因此如果互斥锁有名字为“ExampleName”,事件也有名字为“ExampleName”则发生冲突,通过 GetLastError 函数返回 ERROR_INVALID_HANDLE 错误

更多关于内核对象命名空间的知识可以阅读参考中的链接

未命名互斥锁的同步

  1. 通过线程间(或进程间)复制句柄或者父子句柄继承实现,这里我们主要讲一下复制句柄
  2. 复制句柄:通过该方法可以在两个进程之间传递句柄,但相比于命名句柄和父子继承的方式,这种方式显然更加复杂,它需要在创建句柄的进程和使用句柄的进程间进行通信(如,命名管道,命名共享内存)。另一个需要注意的地方,复制的句柄本质上和源句柄是等同的,你可以理解为指针间的赋值,赋值过后的两个指针实际是指向的相同的区域,任何改变都会影响两个指针指向的区域,句柄也是如此
  3. 语法
BOOL DuplicateHandle(
  [in]  HANDLE   hSourceProcessHandle,
  [in]  HANDLE   hSourceHandle,
  [in]  HANDLE   hTargetProcessHandle,
  [out] LPHANDLE lpTargetHandle,
  [in]  DWORD    dwDesiredAccess,
  [in]  BOOL     bInheritHandle,
  [in]  DWORD    dwOptions
);
  1. 参数
    1. hSourceProcessHandle:源进程的句柄,该进程必须有 PROCESS_DUP_HANDLE 的接入权限。源句柄可以通过 GetCurrentProcess 获得
    2. hSourceHandle:要被复制的句柄,比如互斥锁句柄
    3. hTargetProcessHandle:目标进程的句柄,该进程必须有 PROCESS_DUP_HANDLE 的接入权限。目标句柄可以通过 OpenProcess 获得
    4. lpTargetHandle:注意它是一个指针,指向复制过来的句柄,“LP” 是 long pointer 的缩写
    5. dwDesiredAccess:新句柄的权限设置。一般通过复制得到的句柄的权限范围 ≤ 原句柄
    6. bInheritHandle:该句柄能否被继承
    7. dwOptions:一些可选的配置项,这里不展开

关于句柄复制并非本篇的重点,详细内容移步官方文档

互斥锁的意外终止

比如,当前拥有互斥锁的线程终止,而该线程并未释放互斥锁,此时互斥锁被标记为遗弃(abandoned),它表明互斥锁未被正确释放

其他等待该互斥锁的线程可以获取它,但对应的 wait 函数会返回 WAIT_ABANDONED 来表明互斥锁对象被遗弃,由此表明此时被互斥锁操控的共享资源处于未定义状态(undefined state)

临界区对象

临界区(critical section)对象提供类似与互斥锁的功能,区别在于临界区对象不提供进程间同步,只能提供同一进程中的线程的同步
【注】这里的临界区对象是 Windows 提供的一种用户模式下的线程同步机制,不完全等同于操作系统中的临界区这个概念

参考

  1. Synchronization
  2. 《Windows 核心编程》
  3. Process Security and Access Rights

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/563731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小猫踩球-第14届蓝桥杯省赛Scratch中级组真题第2题

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第137讲。 小猫踩球,本题是2023年5月7日举行的第14届蓝桥杯省赛Scratch图形化编程中级组真题第2题&#xf…

智慧档案馆一体化监控系统设计所需要的10条依据

1.科学性 本项目目标定位为:以科学技术为基础,依靠先进的设备和优越的设计理念、科学客观的管理,利用信息化管理及相关最新技术,将库房实际环境与存储技术、计算机技术、无线自动控制技术、通讯与信息处理技术等先进技术相结合&a…

Python appium搭建app自动化测试环境

目录 前言 App自动化环境安装 安装安卓开发工具 安装模拟器 前言 appium做app自动化测试,环境搭建是比较麻烦的。 也是很多初学者在学习app自动化之时,花很多时间都难跨越的坎。 但没有成功的环境,就没有办法继续后续的使用。 在app自…

面试技术点

一、对热修复、插件化、模块化、组件化有一定研究。 1、模块化 将共享部分或业务模块抽取出来形成独立module。 2、组件化 基于模块化,核心思想是角色的转换,在打包时是library,分离独立的业务组件如微信朋友圈。 3、热修复和插件化种类、…

在Kaggle上使用Stable Diffusion进行AI绘图

前言 因为使用Stable Diffusion进行AI绘图需要GPU,这让其应用得到了限制本文介绍如何在Kaggle中部署Stable Diffusion,并使用免费的P100 GPU进行推理(每周可免费使用30小时),部署好后可以在任意移动端使用。本项目在s…

2023全球最佳医院榜单及简要介绍

作为医学类的访问学者、博士后及联合培养博士们,都希望到世界知名医院进行临床研修交流及科研学习。2023 年世界最佳医院排行榜的发布为申请者提供了目标平台,现知识人网小编整理刊出。 近期,《新闻周刊》和全球数据公司 Statista 推出了2023…

拿了7家大厂offer后,整理出来的笔记.....

我第一次接触自动化是在2016年。那时刚毕业一年有余,组内一直做手工功能测试,大概在2018年9月,部门领导要求测试组引入自动化。组内之前从没有开展过任何自动化,测试主管安排了一个刚入职不久的研究生同事去研究。 当时自己内心还…

UniApp原生插件制作

参考1:UniApp官网-原生插件开发 参考2:uniapp Android 原生插件开发 一、下载安装Android Studio 本部分不在赘述 二、下载UniApp离线SDK 下载地址:Android 离线SDK - 正式版 | uni小程序SDK 三、解压下载文件,并导入Androi…

蓝精灵协会:如何将传统 IP 融入 Web3

作者:Cedric Hervet,联合创始人,创意总监 我和许多项目合作过,并且担任了近 30 年的艺术总监和创意总监。我的方法一直是创造同质化的宇宙,把观众带入并使他们产生梦想。但我也曾系统地寻找过那份额外的感动&#xff1…

微服务解码:揭示API的优势挑战与最佳实践

在当今快节奏的软件开发环境中,微服务已成为一种流行的架构模式。但微服务到底是什么?简而言之,微服务是一种将应用程序构建为松耦合、细粒度服务集合的方式,这些服务通过轻量级协议进行通信。这种架构风格使团队能够独立开发和部…

el-upload上传图片成功,详情页回显base64格式的图片

上传图片,并传给后端图片格式是base64。在详情页需要回显图片在el-upload上,我们发现官网里图片回显时,文件数组里要配置好name和url,如下图: 当我们需要回显base64格式的图片时,我们需要将要回显的文件数组处理成id和…

00后竭尽全力面试腾讯软件测试工程师,难道我只值15k....

不废话,直接重点 一般软件测试的面试分为三轮:笔试,HR面试,技术面试。 前两轮,根据不同企业,或有或无,但最后一个技术面试是企业了解你“行不行”的关键环节,每个企业都会有的。 在…

ChatGPT可能马上取代你!ChatGPT能做什么?

文章目录 前言1.客服机器人2.智能助手3.内部沟通4.个性化推荐5.语音交互6.教育培训7.医疗健康8.社交娱乐9.营销推广10.情感分析11.舆情监测12.知识管理13.金融服务14.物联网15.公共服务16.智能家居17.自动化办公18.交通出行19.游戏娱乐20.智慧城市21.决策支持22.人才招聘23.版权…

圣墟传说H5手工端搭建架设教程

圣墟传说H5手工端搭建架设教程 大家好,我是艾西。今天给大家带来的游戏是由小说改编而来的大型玄幻MMORPG仙侠手游,也是比较老的游戏了虽然你可能没有怎么听过,但总会有一批喜欢的玩家热衷于它。 那么让我们直接进入正题开始操作&#xff1…

ChatGPT:你真的了解网络安全吗?浅谈攻击防御进行时之网络安全新总结

ChatGPT:你真的了解网络安全吗?浅谈网络安全攻击防御进行时 网络安全新总结总结 ChatGPT(全名:Chat Generative Pre-trained Transformer),美国OpenAI 研发的聊天机器人程序,是人工智能技术驱动…

Windows 10 X64 内核对象句柄表解析

fweWindows 很多API函数都会创建和使用句柄(传入参数),句柄代表一个内核对象的内存地址,每个进程都有一个句柄表,它保存着进程拥有的句柄,内核也有一个句柄表 PspCidTable,它保存着整个系统的句柄。 ExpLookupHandleTa…

内网外网分离模式下,通过网关转发,来部署前后端分离的系统

前言 最近为某银行系统部署了一套商城系统,网络环境比较特别,思路记录下,其中商场系统使用前后端分离模式部署。 该银行网络环境: 外网服务器:外网可以访问到它,不能访问外网。 网关服务器:跟…

UE5电脑配置要求是什么?2023虚幻5电脑配置推荐

虚幻引擎对于游戏创作者来说已经不再陌生。该软件为程序员构建和设计终极视频游戏,以创建壮观的游戏场景和流畅的动作。此外,它还处理音效、物理碰撞效果和控制。尤其是人工智能对角色的控制。与其他软件一样,Unreal Engine也有最低系统要求才…

Atcoder beginner contest 302

A - Attack AC代码&#xff1a; #include<iostream> #include<algorithm> #include<cstring> #define int long long using namespace std; signed main() {int a, b;cin >> a >> b;if (a % b 0) cout << a / b << endl;else c…

Springboot +spring security,PasswordEncoder详解与应用

一.简介 在前面的文章有提到过PasswordEncoder: 为什么密码使用{noop}开头呢&#xff1f;也做出了相应的解释&#xff0c;这篇文章了解PasswordEncoder。 二.PassworderEncoder 详解 2.1主要方法 String encode(CharSequence rawPassword)&#xff1a;密码加密boolean matc…