原文地址:http://blog.csdn.NET/u012884354/article/details/46691761

相交进程之间的关系主要有两种,同步与互斥。

所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。

所谓同步,是指散布在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。
  显然,同步是一种更为复杂的互斥,而互斥是一种特殊的同步。
  也就是说互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行,而同步也是不能同时运行,但他是必须要安照某种次序来运行相应的线程(也是一种互斥)!
  总结:互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
  同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

[html] view plaincopy
  1. 读写锁特点:
  2. 1)多个读者可以同时进行读
  3. 2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
  4. 3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
  5. 互斥锁特点:
  6. 一次只能一个线程拥有互斥锁,其他线程只有等待
  7. 互斥锁
  8. pthread_mutex_init()
  9. pthread_mutex_lock()
  10. pthread_mutex_unlock()
  11. 读写锁
  12. pthread_rwlock_init()
  13. pthread_rwlock_rdlock()
  14. pthread_rwlock_wrlock()
  15. pthread_rwlock_unlock()
  16. 条件变量
  17. pthread_cond_init()
  18. pthread_cond_wait()
  19. pthread_cond_signal()

条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法。

举个简单的例子,应用程序A中包含两个线程t1和t2。t1需要在bool变量test_cond为true时才能继续执行,而test_cond的值是由t2来改变的,这种情况下,如何来写程序呢?可供选择的方案有两种:

  • 第一种是t1定时的去轮询变量test_cond,如果test_cond为false,则继续休眠;如果test_cond为true,则开始执行。
  • 第二种就是上面提到的条件变量,t1在test_cond为false时调用cond_wait进行等待,t2在改变test_cond的值后,调用cond_signal,唤醒在等待中的t1,告诉t1 test_cond的值变了,这样t1便可继续往下执行。

    很明显,上面两种方案中,第二种方案是比较优的。在第一种方案中,在每次轮询时,如果t1休眠的时间比较短,会导致cpu浪费很厉害;如果t1休眠的时间比较长,又会导致应用逻辑处理不够及时,致使应用程序性能下降。第二种方案就是为了解决轮询的弊端而生的。然而条件变量在使用的过程中,比较容易出错,如何用得不正确的话,会适得其反的,接下来,我将详细分析如何来使用条件变量,希望能够给在使用条件变量过程中遇到问题的朋友有所帮助。
          在开始介绍之前,需要说明一下,在接下来的介绍中,需要用到互斥锁和条件变量相关的内容,在这里我以Linux下的pthread_mutex_t为互斥锁类型,pthread_cond_t为条件变量类型来进行介绍,对pthread不熟的朋友,可以参考一下linux下的manual。
          1. 下面是把刚开始举的例子翻译后的程序:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    pthread_mutex_t mutex;  ///< 互斥锁
    pthread_cond_t  cond;   ///< 条件变量
    bool test_cond = false;
    /// TODO 初始化mutex和cond/// thread 1:
    pthread_mutex_lock(&mutex);            ///< 1
    while (!test_cond)
    {pthread_cond_wait(&cond, &mutex);  ///< 2,3
    }
    pthread_mutex_unlock(&mutex);          ///< 4
    RunThread1Func();/// thread 2:
    pthread_mutex_lock(&mutex);            ///< 5
    test_cond = true;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);          ///< 6/// TODO 销毁mutex和cond

    通过上面的例子,下面我来介绍一下条件变量在使用过程中需要注意的几点(也是比较容易出错的):
          (1)条件变量的使用过程中,最为关键的一点是互斥锁的使用。细心的朋友应该发现了,我在上面的例子中标了1、2、3、4、5、6个标号。在这里1、4、5、6都是正常的lock/unlock,2、3是需要特别说明的。2是进入pthread_cond_wait后的,pthread_cond_wait调的pthread_mutex_unlock,这样做的目的是为了保证在thread1阻塞wait后,thread2获取同一把锁mutex的时候,能够正常获取(即5,6)。3是thread1被唤醒后,要退出pthead_cond_wait之前,pthread_cond_wait调的pthread_mutex_lock,这样做的目的是为了把mutex的控制权还给调用pthread_cond_wait的线程(即thread1)。整理一下基本的时序为:

    1
    2
    3
    thread 1 lock->thread 1 wait-> thread 1 unlock(in wait)
    ->thread 2 lock->thread 2 signal->thread 2 unlock
    ->thread 1 lock(in wait)->thread 1 unlock

    (2)条件变量使用的过程中,通常会加一个bool或者int的值test_cond来配合使用。这里需要注意的一点是一定要在signal之前来改变test_cond,这样才能保证wait的线程被唤醒后,能够取到正确的test_cond的值,否则后果是不可预测的。

互斥锁和读写锁的区别相关推荐

  1. 互斥锁机制,互斥锁与读写锁区别

    Linux的4种锁机制: 互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象.当获取锁操作失败时,线程会进入睡眠,等待锁释放时被唤醒 读写锁:rwlock,分为读锁和写锁.处于读操作时 ...

  2. java锁(公平锁和非公平锁、可重入锁(又名递归锁)、自旋锁、独占锁(写)/共享锁(读)/互斥锁、读写锁)

    前言 本文对Java的一些锁的概念和实现做个整理,涉及:公平锁和非公平锁.可重入锁(又名递归锁).自旋锁.独占锁(写)/共享锁(读)/互斥锁.读写锁 公平锁和非公平锁 概念 公平锁是指多个线程按照申请 ...

  3. golang:1.并发编程之互斥锁、读写锁详解

    本文转载自junjie,而后稍作修改. 一.互斥锁 互斥锁是传统的并发程序对共享资源进行访问控制的主要手段.它由标准库代码包sync中的Mutex结构体类型代表.sync.Mutex类型(确切地说,是 ...

  4. PHP程序中的文件锁、互斥锁、读写锁使用技巧解析

    文件锁全名叫 advisory file lock, 书中有提及. 这类锁比较常见,例如 mysql, php-fpm 启动之后都会有一个pid文件记录了进程id,这个文件就是文件锁. 这个锁可以防止 ...

  5. DCMTK:定义信号灯,互斥锁和读/写锁的类

    DCMTK:定义信号灯,互斥锁和读/写锁的类 定义信号灯,互斥锁和读/写锁的类 定义信号灯,互斥锁和读/写锁的类 #include "dcmtk/config/osconfig.h" ...

  6. 同步方法中的锁对象_互斥锁与读写锁:如何使用锁完成Go程同步?

    图转自https://colobu.com/2018/12/18/dive-into-sync-mutex/ 这张图容易让人产生误解,容易让人误以为goroutine1获取的锁,只有goroutine ...

  7. 并发编程中常见的锁机制:乐观锁、悲观锁、CAS、自旋锁、互斥锁、读写锁

    文章目录 乐观锁 VS 悲观锁 悲观锁 乐观锁 CAS CAS机制 ABA问题 CAS的优缺点 互斥锁 VS 自旋锁 互斥锁 自旋锁 对比及应用场景 读写锁 实现方式 读写锁 VS 互斥锁 乐观锁 V ...

  8. golang map 锁_go 安全map 实现, 互斥锁和读写锁

    ###互斥锁 其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景 ...

  9. 嵌入式 自旋锁、互斥锁、读写锁、递归锁

    互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁,通常情况下锁操作失败会将该线程 ...

最新文章

  1. 可以卸载什么程序来对计算机进行瘦身,电脑越来越卡了,教你一分钟让电脑瘦身(C盘哪些文件可以删除)-怎么清理电脑内存...
  2. 数据可视化[python-pyecharts]制作中国各省份近三个月新型冠状病毒肺炎变化图
  3. 交叉线和直通线各自用于什么场合?为什么?_都是软电线,BVR与RV有什么不一样?...
  4. [Leetcode] Merge Sorted Array 合并数组
  5. leetcode算法题--礼物的最大价值
  6. XML 解析错误:XML 或文本声明不在实体的开头位置,有效的解决方法
  7. 第2章 Python 数字图像处理(DIP) --数字图像基础5 -- 算术运算、集合、几何变换、傅里叶变换等
  8. linux accept过程,Linux协议栈accept和syn队列问题
  9. JavaScript性能优化【上】-- 内存管理、垃圾回收
  10. python staticmethod规范_Python Staticmethod可以调用另一个本地方法吗?
  11. MyCat分布式数据库集群架构工作笔记0008---Mycat主--从复制原理
  12. 【万里征程——Windows App开发】使用华丽丽的字体
  13. grub引导程序适用范围
  14. fzu 2204 7 dp
  15. [bzoj2115][Wc2011] Xor
  16. 发那可g10_fanuc系统中的G10
  17. Hive3.1.2安装指南
  18. 发链(FAB)技术有望突破区块链交易瓶颈
  19. 不对齐 谷歌浏览器_谷歌浏览器input上下不对齐兼容解决办法
  20. 计算机专业一句话介绍自己,来聊聊,你会如何用一句话介绍自己的专业?

热门文章

  1. highCharts使用中问题总结
  2. NOIP2018划水记
  3. linux下的静态库与动态库
  4. Handle/Body pattern(Wrapper pattern)
  5. Java并发编程实战 第14章 构建自定义的同步工具
  6. iis发布网站怎么支持.json文件
  7. Qt 【关于控件样式,鼠标进入、离开、点击】
  8. 行内元素中间出现空隙
  9. SharePoint GridView的使用2——DataSourceView的使用
  10. 书写README的各种markdown语法