1、第11章线程间同步机制 互斥锁通信机制互斥锁通信机制 条件变量通信机制条件变量通信机制 读写锁通信机制读写锁通信机制 线程与信号线程与信号 2022-1-202互斥锁基本原理 互斥以排他方式防止共享数据被并发修改。互斥锁是一个二元变量,其状态为开锁(允许0)和上锁(禁止1),将某个共享资源与某个特定互斥锁绑定后,对该共享资源的访问如下操作:(1)在访问该资源前,首先申请该互斥锁,如果该互斥处于开锁状态,则申请到该锁对象,并立即占有该锁(使该锁处于锁定状态),以防止其它线程访问该资源;如果该互斥锁处于锁定状态,默认阻塞等待;(2)只有锁定该互斥锁的进程才能释放该互斥锁。其它线程的释放操作无效。2
2、022-1-203互斥锁基本操作函数 功能函数初始化互斥锁pthread_mutex_init阻塞申请互斥锁pthread_mutex_lock释放互斥锁pthread_mutex_unlock非阻塞申请互斥锁pthread_mutex_trylock销毁互斥锁pthread_mutex_destroy2022-1-20人民邮电出版社出版杨宗德编著4 pthread_mutex_init 2022-1-205申请互斥锁 2022-1-206释放互斥锁 第11章线程间同步机制 互斥锁通信机制互斥锁通信机制 条件变量通信机制条件变量通信机制 读写锁通信机制读写锁通信机制 线程与信号线程与信号 20
3、22-1-208条件变量基本原理互斥锁不能解决的问题 2022-1-209如果只使用互斥锁,可能导致do_something()永远不会执行,这是程序员所不期望的,如下分析所示: 线程A抢占到互斥锁,执行操作,完成后i=4,j=6;然后释放互斥锁; 线程A和线程B都有可能抢占到锁,如果B抢占到,条件不满足,退出;如果线程A抢占到,则执行操作,完成后i=5,j=5;然后释放互斥锁; 同理,线程A和线程B都有可能抢占到锁,如果B抢占到,则条件满足,do_something()得以执行,得到预期结果。但如果此时A没有抢占到,执行操作后i=6,j=4,此后i等于j的情况永远不会发生。互斥锁不能解决的问
4、题 2022-1-2010条件变量解决的问题2022-1-2011条件变量基本操作 功能函数初始化条件变量pthread_cond_init阻塞等待条件变量pthread_cond_wait通知等待该条件变量的第1个线程pthread_cond_signal在指定的时间之内阻塞等待条件变量pthread_cond_timedwait通知等待该条件变量的所有线程pthread_cond_broadcast销毁条件变量状态pthread_cond_destroy2022-1-2012条件变量应用 见书上例程。第11章线程间同步机制 互斥锁通信机制互斥锁通信机制 条件变量通信机制条件变量通信机制 读
5、写锁通信机制读写锁通信机制 线程与信号线程与信号 2022-1-2014读写锁通信机制 在对数据的读写应用中,更多的是读操作,而写操作较少,例如对数据库数据的读写应用。为了满足当前能够允许多个读出,但只允许一个写入的需求,线程提供了读写锁来实现。其基本原则如下:(1)如果有其它线程读数据,则允许其它线程执行读操作,但不允许写操作;(2)如果有其它线程写数据,则其它线程的读、写操作均允许。因此,其将该锁分为了读锁和写锁。(1)如果某线程申请了读锁,其它线程可以再申请读锁,但不能申请写锁;(2)如果某线程申请了写锁,则其它线程不能申请读锁,也不能申请写锁。定义读写锁对象的代码如下:pthread_
6、rwlock_trwlock;/全局变量2022-1-2015读写锁基本操作 功能函数初始化读写锁pthread_rwlock_init阻塞申请读锁pthread_rwlock_rdlock非阻塞申请读锁pthread_rwlock_tryrdlock阻塞申请写锁pthread_rwlock_wrlock非阻塞申请写锁pthread_rwlock_trywrlock释放锁(无论是读锁还是写锁)pthread_rwlock_unlock销毁读写锁pthread_rwlock_destroy第11章线程间同步机制 互斥锁通信机制互斥锁通信机制 条件变量通信机制条件变量通信机制 读写锁通信机制读写锁
7、通信机制 线程与信号线程与信号 2022-1-2017线程在信号操作时有以下特性 (1)每一个线程可以向别的线程发送信号。pthread_kill()函数用来完成这一操作。(2)每一个线程可以设置自己的信号阻塞集合。pthread_sigmask()函数用来完成这一操作,其类似于进程的sigprocmask()函数。(3)每个线可以设置针对某信号处理的方式,但同一进程中对某信号的处理方式只能有一个有效,即最后一次设置的处理方式。(4)如果别的进程向当前进程中发送一个信号,由哪个线程处理是未知的。2022-1-2018线程信号管理 2022-1-2019pthread_sigmask调用线程的信号掩码 2022-1-2020线程信号应用实例 见教材示例。