news 2026/8/9 10:24:00

多线程核心:互斥与同步

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多线程核心:互斥与同步

在多线程开发中,互斥同步是解决 “资源竞争” 与 “执行顺序” 问题的核心技术,本文结合原理 + 代码 + 图示详细解析。

一、互斥(Mutex):临界资源的排他性访问

1. 基本概念

  • 临界资源:多线程中会被 “读写操作” 的资源(全局变量、文件、硬件设备等)。
  • 排他访问:同一时刻,只能有一个线程访问临界资源。

2. 问题场景

多线程并发执行时,若同时操作临界资源,会出现数据不一致:比如线程 A 执行A += 1(实际是 “读 A→运算→写 A” 三步),但线程 B 可能在 A “读” 和 “写” 之间插入操作,导致最终结果错误。

3. 解决方案:互斥锁

通过互斥锁(Mutex)保证 “临界区代码” 的原子性(同一时刻只有一个线程执行)。

互斥锁的使用步骤

定义互斥锁

初始化互斥锁

加锁(进入临界区)

执行临界区代码

解锁(退出临界区)

销毁互斥锁

定义互斥锁

初始化互斥锁

加锁(进入临界区)

执行临界区代码

解锁(退出临界区)

销毁互斥锁

互斥锁相关函数(POSIX 标准)

运行

// 1. 定义互斥锁 pthread_mutex_t mutex; // 2. 初始化互斥锁 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); // 参数:attr=NULL表示默认属性;返回值:成功0/失败非0 // 3. 加锁(阻塞等待,直到拿到锁) int pthread_mutex_lock(pthread_mutex_t *mutex); // 说明:加锁后,其他线程无法进入临界区 // 4. 解锁 int pthread_mutex_unlock(pthread_mutex_t *mutex); // 说明:解锁后,其他线程可竞争锁 // 5. 销毁互斥锁 int pthread_mutex_destroy(pthread_mutex_t *mutex);
互斥锁注意事项
  • 临界区代码要尽量短(不要在临界区里 sleep、做耗时操作);
  • 加锁和解锁必须是同一个线程(避免 “锁泄露”)。

二、同步(Semaphore):有顺序的排他访问

1. 基本概念

同步是带顺序的互斥—— 不仅要 “排他访问资源”,还要保证 “线程按指定顺序执行”。

关系:互斥是同步的超集,同步是互斥的一个特例。

2. 解决方案:信号量

信号量(Semaphore)是一种 “计数器”,通过P/V操作控制资源的 “申请” 与 “释放”,既可以实现互斥,也可以实现同步。

信号量的使用步骤

定义信号量

初始化信号量

P操作(申请资源)

执行代码

V操作(释放资源)

销毁信号量

定义信号量

初始化信号量

P操作(申请资源)

执行代码

V操作(释放资源)

销毁信号量

信号量相关函数(POSIX 标准)

运行

// 1. 定义信号量 sem_t sem; // 2. 初始化信号量 int sem_init(sem_t *sem, int pshared, unsigned int value); // 参数: // - pshared:0=线程间共享;非0=进程间共享 // - value:信号量初始值(资源数量) // 返回值:成功0/失败-1 // 3. P操作(申请资源:sem -= 1) int sem_wait(sem_t *sem); // 说明:若sem>0,直接减1并执行;若sem=0,阻塞等待 // 4. V操作(释放资源:sem += 1) int sem_post(sem_t *sem); // 说明:释放后,唤醒等待的线程 // 5. 销毁信号量 int sem_destroy(sem_t *sem);
信号量的典型场景
  • 互斥:初始值设为 1(同一时刻 1 个线程访问资源);
  • 同步:初始值设为 0(控制线程执行顺序,比如线程 A 执行完再让线程 B 执行)。

三、互斥 VS 同步:核心区别

特性互斥(Mutex)同步(Semaphore)
核心目标保护临界资源,避免竞争控制线程执行顺序
资源数量仅支持 “1 个资源” 的排他访问支持 “多个资源” 的并发访问(value>1)
操作主体加锁 / 解锁必须是同一个线程P/V 操作可以是不同线程
临界区代码必须短小(不能 sleep)可包含耗时操作(适当 sleep)

四、死锁:多线程的 “陷阱”

当多个线程互相等待对方持有的资源时,会陷入 “永久阻塞” 状态,这就是死锁。

死锁的 4 个必要条件

  1. 互斥条件:资源同一时刻只能被一个线程使用;
  2. 请求与保持条件:线程申请新资源时,不释放已持有的资源;
  3. 不剥夺条件:线程已持有的资源,不能被强制剥夺;
  4. 循环等待条件:多个线程形成 “循环等待资源” 的关系。

如何避免死锁

  • 固定顺序申请资源;
  • 申请资源时超时放弃
  • 减少资源的 “持有时间”。

五、总结

  • 互斥是 “保护资源”,用 Mutex 实现;
  • 同步是 “控制顺序”,用 Semaphore 实现;
  • 死锁是多线程的 “雷区”,需通过资源申请顺序、超时等方式避免。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/8 22:11:23

大数据领域数据可视化:从数据到知识的转化

大数据领域数据可视化:从数据到知识的转化 关键词:大数据、数据可视化、数据到知识转化、可视化技术、信息传递 摘要:本文聚焦于大数据领域的数据可视化,深入探讨了如何将海量、复杂的数据转化为易于理解和分析的知识。首先介绍了数据可视化在大数据背景下的重要性和应用范…

作者头像 李华
网站建设 2026/8/8 17:13:29

39、邮件和新闻服务器管理指南

邮件和新闻服务器管理指南 1. 邮件转发与别名设置 若要在将邮件转发到指定地址的同时,在原系统保留一份邮件副本,可在 .forward 文件中添加如下行: wilbur@somewhereelse.net, wilbur\只需追加用户名,并以反斜杠结尾。行尾的反斜杠 ( \ ) 可防止 sendmail 重复转…

作者头像 李华
网站建设 2026/8/9 5:58:41

未来已来:AI原生文本生成将如何重塑内容生态?

未来已来:AI原生文本生成将如何重塑内容生态? 关键词:AI原生文本生成、内容生态、生成式AI、AIGC、大语言模型(LLM)、内容生产链、人机协同 摘要:当AI从“辅助工具”进化为“原生创作者”,内容生…

作者头像 李华
网站建设 2026/8/9 5:58:34

springboot+jspm关于java的酒店预订管理系统_7co146y7

目录已开发项目效果实现截图开发技术介绍系统开发工具:核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/8/9 5:58:26

springboot+jspm大学生教务评教系统的设计与实现_h6604vab

目录已开发项目效果实现截图开发技术介绍系统开发工具:核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/8/9 5:58:19

水下机器人控制与路径跟踪仿真

增量PID轨迹跟踪 MATLAB仿真 水下机器人控制 无人船无人艇 USV路径跟随大家好!今天我将和大家分享一个有趣的主题:增量PID轨迹跟踪在水下机器人中的应用。这个主题结合了控制理论、算法优化和实际工程应用,非常值得探讨。首先,我想…

作者头像 李华