信号量 互斥锁 条件变量的区别
条件变量——精选推荐

条件变量与互斥锁不同,条件变量是⽤来等待⽽不是⽤来上锁的。
条件变量⽤来⾃动阻塞⼀个线程,直到某特殊情况发⽣为⽌。
通常条件变量和互斥锁同时使⽤。
条件变量使我们可以睡眠等待某种条件出现。
条件变量是利⽤线程间共享的全局变量进⾏同步的⼀种机制,主要包括两个动作:⼀个线程等待"条件变量的条件成⽴"⽽挂起;另⼀个线程使"条件成⽴"(给出条件成⽴信号)。
条件的检测是在互斥锁的保护下进⾏的。
如果⼀个条件为假,⼀个线程⾃动阻塞,并释放等待状态改变的互斥锁。
如果另⼀个线程改变了条件,它发信号给关联的条件变量,唤醒⼀个或多个等待它的线程,重新获得互斥锁,重新评价条件。
如果两进程共享可读写的内存,条件变量可以被⽤来实现这两进程间的线程同步。
使⽤条件变量之前要先进⾏初始化。
可以在单个语句中⽣成和初始化⼀个条件变量如:pthread_cond_tmy_condition=PTHREAD_COND_INITIALIZER;(⽤于进程间线程的通信)。
可以利⽤函数pthread_cond_init动态初始化。
条件变量分为两部分: 条件和变量. 条件本⾝是由互斥量保护的. 线程在改变条件状态前先要锁住互斥量. 它利⽤线程间共享的全局变量进⾏同步的⼀种机制。
相关的函数如下:1int pthread_cond_init(pthread_cond_t*cond,pthread_condattr_t*cond_attr); 2int pthread_cond_wait(pthread_cond_t*cond,pthread_mutex_t*mutex); 3int pthread_cond_timewait(pthread_cond_t*cond,pthread_mutex*mutex,const timespec*abstime); 4int pthread_cond_destroy(pthread_cond_t*cond); 5int pthread_cond_signal(pthread_cond_t*cond); 6int pthread_cond_broadcast(pthread_cond_t*cond); //解除所有线程的阻塞简要说明:(1)初始化.init()或者pthread_cond_t cond=PTHREAD_COND_INITIALIER;属性置为NULL(2)等待条件成⽴.pthread_wait,pthread_timewait.wait()释放锁,并阻塞等待条件变量为真timewait()设置等待时间,仍未signal,返回ETIMEOUT(加锁保证只有⼀个线程wait)(3)激活条件变量:pthread_cond_signal,pthread_cond_broadcast(激活所有等待线程)(4)清除条件变量:destroy;⽆线程等待,否则返回EBUSY详细说明1. 初始化:条件变量采⽤的数据类型是pthread_cond_t, 在使⽤之前必须要进⾏初始化, 这包括两种⽅式:静态: 可以把常量PTHREAD_COND_INITIALIZER给静态分配的条件变量.动态: pthread_cond_init函数, 是释放动态条件变量的内存空间之前, 要⽤pthread_cond_destroy对其进⾏清理.#include <pthread.h> int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr); intpthread_cond_destroy(pthread_cond_t *cond); 成功则返回0, 出错则返回错误编号.当pthread_cond_init的attr参数为NULL时, 会创建⼀个默认属性的条件变量; ⾮默认情况以后讨论.2. 等待条件:#include <pthread.h> int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restric mutex); intpthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout); 成功则返回0, 出错则返回错误编号.这两个函数分别是阻塞等待和超时等待.等待条件函数等待条件变为真, 传递给pthread_cond_wait的互斥量对条件进⾏保护, 调⽤者把锁住的互斥量传递给函数. 函数把调⽤线程放到等待条件的线程列表上, 然后对互斥量解锁, 这两个操作是原⼦的. 这样便关闭了条件检查和线程进⼊休眠状态等待条件改变这两个操作之间的时间通道, 这样线程就不会错过条件的任何变化.当pthread_cond_wait返回时, 互斥量再次被锁住.3. 通知条件:#include <pthread.h> int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); 成功则返回0,出错则返回错误编号.这两个函数⽤于通知线程条件已经满⾜. 调⽤这两个函数, 也称向线程或条件发送信号. 必须注意, ⼀定要在改变条件状态以后再给线程发送信号.⽰例程序#include <stdio.h>#include <pthread.h>pthread_mutex_t mutex;pthread_cond_t cond;void *thread1(void *arg){pthread_cleanup_push(pthread_mutex_unlock, &mutex);//提供函数回调保护while (1) {printf("thread1 is running\n");pthread_mutex_lock(&mutex);pthread_cond_wait(&cond, &mutex);printf("thread1 applied the condition\n");pthread_mutex_unlock(&mutex);sleep(4);}pthread_cleanup_pop(0);}void *thread2(void *arg){while (1) {printf("thread2 is running\n");pthread_mutex_lock(&mutex);pthread_cond_wait(&cond, &mutex);printf("thread2 applied the condition\n");pthread_mutex_unlock(&mutex);sleep(1);}}int main(){pthread_t thid1, thid2;printf("condition variable study!\n");pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond, NULL);pthread_create(&thid1, NULL, (void *) thread1, NULL); pthread_create(&thid2, NULL, (void *) thread2, NULL); do {pthread_cond_signal(&cond);} while (1);sleep(20);pthread_exit(0);return 0;}条件变量与互斥锁、信号量的区别1.互斥锁必须总是由给它上锁的线程解锁,信号量的挂出即不必由执⾏过它的等待操作的同⼀进程执⾏。
信号量、互斥量、同步变量、条件变量和事件变量

信号量、互斥量、同步变量、条件变量和事件变量信号量:信号量(Semaphore),有时被称为信号灯,是在多线程环境下使⽤的⼀种设施,是可以⽤来保证两个或多个关键代码段不被调⽤。
在进⼊⼀个关键代码段之前,线程必须获取⼀个信号量;⼀旦该关键代码段完成了,那么该线程必须释放信号量。
其它想进⼊该关键代码段的线程必须等待直到第⼀个线程释放信号量。
为了完成这个过程,需要创建⼀个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的⾸末端。
确认这些信号量VI引⽤的是初始创建的信号量。
互斥量:互斥量是⼀个可以处于两态之⼀的变量:解锁和加锁。
这样,只需要⼀个位表⽰它,不过实际上,常常使⽤⼀个,0表⽰解锁,⽽其他所有的值则表⽰加锁。
互斥量使⽤两个过程。
当⼀个(或进程)需要访问时,它调⽤mutex_lock。
如果该互斥量当前是解锁的(即临界区可⽤),此调⽤成功,调⽤线程可以⾃由进⼊该临界区。
另⼀⽅⾯,如果该互斥量已经加锁,调⽤线程被阻塞,直到在临界区中的线程完成并调⽤mutex_unlock。
如果多个线程被阻塞在该互斥量上,将随机选择⼀个线程并允许它获得锁。
同步变量:条件变量:事件变量:四种进程或线程同步互斥的控制⽅法1、临界区:通过对多线程的串⾏化来访问公共资源或⼀段代码,速度快,适合控制数据访问。
2、互斥量:为协调共同对⼀个共享资源的单独访问⽽设计的。
3、信号量:为控制⼀个具有有限数量⽤户资源⽽设计。
4、事件:⽤来通知线程有⼀些事件已发⽣,从⽽启动后继任务的开始。
临界区(Critical Section)保证在某⼀时刻只有⼀个线程能访问数据的简便办法。
在任意时刻只允许⼀个线程对共享资源进⾏访问。
如果有多个线程试图同时访问临界区,那么在有⼀个线程进⼊后其他所有试图访问此临界区的线程将被挂起,并⼀直持续到进⼊临界区的线程离开。
临界区在被释放后,其他线程可以继续抢占,并以此达到⽤原⼦⽅式操作共享资源的⽬的。
互斥锁 条件变量 信号量 区别

互斥锁条件变量信号量区别
一、根本的区别
互斥:
锁的本质是一种同步技术,其原理是阻止多个线程同时访问某个资源,保证其他线程在某一时刻只有一个线程可以访问此资源。
通常情况下,互斥锁可以同步一个复杂的数据结构或某一个固定的资源,它可以使一个进程在完成特定操作之前锁住共享资源,其它进程或线程只能等待该进程释放锁后才能访问该资源,这种机制称为互斥。
条件变量:
条件变量能够控制哪些线程被挂起和唤醒,而不是去控制线程本身操作资源的依次,他提供一种机制,当某个特定时刻,特定需求满足时,就唤醒其它等待线程,减少线程等待时间。
信号量:
信号量也是一种线程同步技术,其本质是一个计数器,用来统计可以访问的资源的个数,其可以实现资源的限制,比如一次最多只有5个线程可以访问某个资源,其它线程需要等待。
二、各自的特点
互斥锁:
互斥量的特点是,只有当资源上没有线程使用时,才能进行访问,所有,它用于控制多个进程对共享数据的访问。
条件变量:
条件变量能够控制哪些线程被挂起和唤醒,而不是去控制线程本身操作资源的依次,他提供一种机制,当某个特定时刻,特定需求满足时,就唤醒其它等待线程,减少线程等待时间。
信号量:
信号量能够控制进程在某个资源有多少个可用,一旦可用资源耗尽,就可以使其他进程等待,直到有更多的可用资源,以保证有序的访问。
操作系统的同步机制

操作系统的同步机制
操作系统中的同步机制是指多个进程或线程之间的协作,以保证它们之间的并发执行不会出现冲突或错误。
同步机制包括互斥锁、条件变量、信号量等技术,它们的作用是实现对共享资源的访问控制、进程的协调和通信。
互斥锁(Mutex)是最基本的同步机制,它用于保护共享变量的访问,一次只允许一个线程获得锁访问共享变量。
条件变量(Condition Variable)则用于线程之间的通信,当一个线程需要等待某个条件满足时,可以调用条件变量的wait方法,使自己阻塞,当条件满足后,其他线程唤醒该线程。
信号量(Semaphore)则是一种更高级的同步机制,它可以实现多个线程之间的协作,当某个线程需要访问共享资源时,它会尝试获取信号量,如果成功获取则可以访问共享资源,否则会被阻塞。
当线程访问完共享资源后,需要释放信号量,以便其他线程可以获取资源。
除了这些同步机制,操作系统还提供了进程间通信(IPC)的方式,包括管道、消息队列、共享内存等。
这些机制可以让进程之间进行数据交换和协同工作,实现更复杂的应用场景。
总之,同步机制是操作系统中非常重要的概念,对于开发高并发、多线程应用非常关键。
理解和掌握同步机制可以帮助程序员避免并发问题,提高应用的性能和稳定性。
- 1 -。
信号量和条件变量的异同点

信号量和条件变量的异同点信号量和条件变量是操作系统中常用的同步机制,它们都可以用于线程之间的通信和协调,但在实际应用中有着不同的作用和特点。
我们来看看信号量。
信号量是一种用于控制对共享资源的访问的同步原语。
它通常用于限制同时访问某一资源的线程数量,或者用于实现生产者-消费者模式等场景。
信号量有两种类型:二进制信号量和计数信号量。
二进制信号量的取值只能为0或1,用于实现互斥访问共享资源;而计数信号量的取值可以大于1,用于控制对资源的访问数量。
与信号量类似,条件变量也是一种线程间同步的机制。
条件变量通常与互斥锁一起使用,用于在线程间传递信号和实现线程的等待和唤醒操作。
条件变量通过wait和signal操作来实现线程的等待和唤醒。
当一个线程调用wait操作时,它会释放互斥锁并进入等待状态,直到另一个线程调用signal操作唤醒它。
信号量和条件变量在功能上有一定的相似之处,都可以用于线程的同步和互斥控制。
但它们之间也存在一些明显的区别。
信号量是一种更为通用的同步原语,可以用于实现不同的同步策略,如互斥访问、资源控制等;而条件变量主要用于线程间的等待和唤醒操作,通常与互斥锁一起使用。
信号量是一个整数值,可以通过P和V操作进行增减;而条件变量是一个线程间共享的标识,用于线程的等待和唤醒。
信号量是一种无记忆的同步原语,它只关注当前资源的数量和可用性;而条件变量是一种有记忆的同步原语,可以用于线程间传递信号和信息。
在使用上,信号量通常用于控制对共享资源的访问,通过增减操作来实现资源的互斥访问;而条件变量通常用于线程的等待和唤醒操作,通过wait和signal操作来实现线程的同步和协调。
信号量和条件变量在操作系统中都扮演着重要的角色,它们都可以用于线程的同步和互斥控制。
虽然它们在功能上有一定的相似之处,但在实际应用中有着不同的作用和特点。
正确地选择和使用信号量和条件变量,可以有效地提高程序的性能和可靠性,实现线程间的协调和通信。
信号量、互斥锁和条件变量的区别

信号量、互斥锁和条件变量的区别⼀、1、互斥锁总是必须由给其上锁的线程解锁,信号量的挂出确不必由执⾏过它的等待操作的同⼀线程执⾏。
⽣产者与消费者伪代码2、互斥锁要么被锁住,要么被解锁(⼆值状态,类似于⼆值信号量)3、既然信号量有⼀个与之关联的状态(它的数值),那么信号量的挂出操作总是被记住。
然⽽当向⼀个条件变量发送信号时,如果没有线程等待在该条件变量上,那么信号将丢失。
ps:提供信号量的原因是,在进程间同步的情况下,若没有涉及到共享内存区时,需要使⽤信号量。
⼆、 1、posix提供量中信号量:有名信号量和基于内存的信号量,后者被称为⽆名信号量。
有名信号量如下图所⽰:内存信号量(⽆名信号量)如下图所⽰:三、有名信号量 sem_open:创建⼀个新的有名信号量或者打开⼀个已经存在的有名信号量。
有名信号量既可⽤于线程间同步,也可⽤于进程间同步。
头⽂件:#include <semaphore.h>函数原型:sem_t *sem_open(const char *name,int oflag,mode_t mode,unsigned int value);参数:name 信号量的外部名字oflag 选择创建或打开⼀个现有的信号量mode 权限位value 信号量初始值oflag参数可以是0、O_CREAT(创建⼀个信号量)或O_CREAT|O_EXCL(如果没有指定的信号量就创建),如果指定了O_CREAT,那么第三个和第四个参数是需要的;其中mode参数指定权限位,value参数指定信号量的初始值,通常⽤来指定共享资源的书⾯。
该初始不能超过SEM_VALUE_MAX,这个常值必须低于为32767。
⼆值信号量的初始值通常为1,计数信号量的初始值则往往⼤于1。
如果指定了O_CREAT(⽽没有指定O_EXCL),那么只有所需的信号量尚未存在时才初始化它。
所需信号量已存在条件下指定O_CREAT 不是⼀个错误。
线程同步互斥的方法

线程同步互斥的方法
线程同步和互斥是为了保证多个线程之间的资源访问的正确性和顺序性。
以下是一些常见的线程同步互斥的方法:
1. 互斥锁(Mutex):互斥锁是一种最基本的线程同步方法,它保证了在同一时刻只有一个线程可以访问某个资源。
当一个线程获得互斥锁之后,其他线程必须等待该线程释放锁之后才能继续访问。
2. 信号量(Semaphore):信号量是一种更为灵活的线程同步方法。
它可以实现多个线程之间的互斥和同步,可以控制同时访问某个资源的线程数量。
3. 条件变量(Condition):条件变量是一种线程同步方法,它可以实现多个线程之间的协调和通信。
线程可以通过条件变量等待某个条件的满足,当条件满足时,其他线程可以通过条件变量来通知等待的线程。
4. 原子操作(Atomic Operation):原子操作是一种最轻量级的线程同步方法,它可以保证某个操作的执行是不可分割的,不会被其他线程打断。
原子操作通常使用特殊的CPU指令来实现。
5. 读写锁(ReadWriteLock):读写锁是一种用于读写操作的线程同步方法。
它允许多个线程同时读取某个资源,但是只有一个线程可以写入资源。
读写锁可以提高多线程读操作的并发性能。
以上是一些常见的线程同步互斥的方法,根据具体的场景和需求,选择合适的方法可以提高多线程程序的性能和稳定性。
多线程下的消息机制

多线程下的消息机制多线程下的消息机制是指在多线程环境中,为了线程之间进行通信和交流而建立的一种机制。
在多线程编程中,由于线程之间的并发执行,线程之间需要进行数据共享、状态同步等操作,因此需要一种机制来实现线程之间的通信。
常见的多线程下的消息机制包括互斥量、条件变量、信号量和消息队列等。
一、互斥量(Mutex)互斥量是一种最常见的多线程通信机制,用于实现线程之间的互斥访问共享资源。
互斥量可以防止多个线程同时访问共享资源,只有获得互斥量的线程才能执行临界区代码,其他线程则需要等待。
通过锁定和解锁互斥量来控制线程的访问。
互斥量可以避免多个线程同时访问共享资源,从而保证数据的安全性。
二、条件变量(Condition Variable)条件变量是一种多线程通信的高级机制,用于在线程之间等待和通知的机制。
条件变量可以利用互斥量来控制线程的访问,并在特定条件满足时唤醒等待的线程。
条件变量可以实现线程之间的同步和消息传递。
三、信号量(Semaphore)信号量是一种用于管理有限资源的多线程通信机制。
信号量可以控制线程的访问数量,允许同时访问的线程数量受限。
当线程需要访问资源时,需要申请信号量;当资源被释放时,需要释放信号量。
通过信号量可以实现线程之间的同步和互斥访问。
四、消息队列(Message Queue)消息队列是一种用于线程间通信的机制,可以实现线程之间的消息传递和异步通信。
消息队列通过一个先进先出的队列,将消息从发送者传递到接收者。
发送者将消息放入队列中,接收者从队列中取出消息并进行处理。
消息队列可以实现线程之间的解耦和异步通信。
总结:多线程下的消息机制是实现线程间通信和交流的重要机制,它可以实现线程之间的同步和互斥访问,保证共享资源的安全性,同时也可以实现线程之间的解耦和异步通信。
不同的消息机制适用于不同的场景和需求,开发人员需要根据具体情况选择合适的消息机制来实现线程之间的通信。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
信号量互斥锁条件变量的区别(这是我在网上找到的一个解释,个人认为讲的很好,供同学们参考一下,如果看不懂可以与我交流)
信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在哪里)。
而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这个资源。
比如对全局变量的访问,有时要加锁,操作完了,在解锁。
有的时候锁和信号量会同时使用的”
也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。
而线程互斥量则是“锁住某一资源”的概念,在锁定期间内,其他线程无法对被保护的数据进行操作。
在有些情况下两者可以互换。
两者之间的区别:
作用域
信号量: 进程间或线程间(linux仅线程间)
互斥锁: 线程间
上锁时
信号量: 只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value 减一。
若value值不大于0,则sem_wait阻塞,直到sem_post释放后value值加一
互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源
成功后否则就阻塞
以下是信号灯(量)的一些概念:
信号灯与互斥锁和条件变量的主要不同在于”灯”的概念,灯亮则意味着资源可用,灯灭则意味着不可用。
如果说后两中同步方式侧重于”等待”操作,即资源不可用的话,信号灯机制则侧重于点灯,即告知资源可用;没有等待线程的解锁或激发条件都是没有意义的,而没有等待灯亮的线程的点灯操作则有效,且能保持灯亮状态。
当然,这样的操作原语也意味着更多的开销。
信号灯的应用除了灯亮/灯灭这种二元灯以外,也可以采用大于1的灯数,以表示资源数大于1,这时可以称之为多元灯。
1.创建和注销
POSIX信号灯标准定义了有名信号灯和无名信号灯两种,但LinuxThreads的实现仅有无名灯,同时有名灯除了总是可用于多进程之间以外,在使用上与无名灯并没有很大的区别,因此下面仅就无名灯进行讨论。
int sem_init(sem_t *sem, int pshared, unsigned int value)
这是创建信号灯的API,其中value为信号灯的初值,pshared表示是否为多进程共享而不仅仅是用于一个进程。
LinuxThreads没有实现多进程共享信号灯,因此所有非0值的pshared输入都将使sem_init()返回-1,且置errno为ENOSYS。
初始化好的信号灯由sem变量表征,用于以下点灯、灭灯操作。
int sem_destroy(sem_t * sem)
被注销的信号灯sem要求已没有线程在等待该信号灯,否则返回-1,且置errno为EBUSY。
除此之外,LinuxThreads的信号灯注销函数不做其他动作。
2.点灯和灭灯
int sem_post(sem_t * sem)
点灯操作将信号灯值原子地加1,表示增加一个可访问的资源。
int sem_wait(sem_t * sem)
int sem_trywait(sem_t * sem)
sem_wait()为等待灯亮操作,等待灯亮(信号灯值大于0),然后将信号灯原子地减1,并返回。
sem_trywait()为sem_wait()的非阻塞版,如果信号灯计数大于0,则原子地减1并返回0,否则立即返回-1,errno置为EAGAIN。
3.获取灯值
int sem_getvalue(sem_t * sem, int * sval)
读取sem中的灯计数,存于*sval中,并返回0。
4.其他
sem_wait()被实现为取消点,而且在支持原子”比较且交换”指令的体系结构上,sem_post()是唯一能用于异步信号处理函数的POSIX异步信号安全的API。
----------------------------
线程同步:何时互斥锁不够,还需要条件变量?
假设有共享的资源sum,与之相关联的mutex 是lock_s.假设每个线程对sum的操作很简单的,与sum的状态无关,比如只是sum++.那么只用mutex足够了.程序员只要确保每个线程操作前,取得lock,然后sum++,再unlock即可.每个线程的代码将像这样
add()
{
pthread_mutex_lock(lock_s);
sum++;
}
如果操作比较复杂,假设线程t0,t1,t2的操作是sum++,而线程t3则是在sum到达100的时候,打印出一条信息,并对sum清零. 这种情况下,如果只用mutex, 则t3需要一个循环,每个循环里先取得lock_s,然后检查sum的状态,如果sum>=100,则打印并清零,然后unlock.如果
sum<100,则unlock,并sleep()本线程合适的一段时间.
这个时候,t0,t1,t2的代码不变,t3的代码如下
print()
{
while (1)
{
pthread_mutex_lock(lock_s);
if(sum<100)
{
printf(“sum reach 100!”);
pthread_mutex_unlock(lock_s);
}
else
{
pthread_mutex_unlock(lock_s);
my_thread_sleep(100);
return OK;
}
}
}
这种办法有两个问题
1) sum在大多数情况下不会到达100,那么对t3的代码来说,大多数情况下,走的是else分支,只是lock和unlock,然后sleep().这浪费了CPU处理时间.
2) 为了节省CPU处理时间,t3会在探测到sum没到达100的时候sleep()一段时间.这样却又带来另外一个问题,亦即t3响应速度下降.可能在sum到达200的时候,t4才会醒过来.
3) 这样,程序员在设置sleep()时间的时候陷入两难境地,设置得太短了节省不了资源,太长了又降低响应速度.真是难办啊!
这个时候,condition variable内裤外穿,从天而降,拯救了焦头烂额的你.
你首先定义一个condition variable.
pthread_cond_t cond_sum_ready=PTHREAD_COND_INITIALIZER;
t0,t1,t2的代码只要后面加两行,像这样
add()
{
sum++;
pthread_mutex_unlock(lock_s);
if(sum>=100)
pthread_cond_signal(&cond_sum_ready);
}
而t3的代码则是
print
{
pthread_mutex_lock(lock_s);
while(sum<100)
pthread_cond_wait(&cond_sum_ready, &lock_s);
printf(“sum is over 100!”);
sum=0;
pthread_mutex_unlock(lock_s);
return OK;
}
注意两点:
1) 在thread_cond_wait()之前,必须先lock相关联的mutex, 因为假如目标条件未满
足,pthread_cond_wait()实际上会unlock该mutex, 然后block,在目标条件满足后再重新lock 该mutex, 然后返回.
2) 为什么是while(sum<100),而不是if(sum<100) ?这是因为在pthread_cond_signal()和pthread_cond_wait()返回之间,有时间差,假设在这个时间差内,还有另外一个线程t4又把sum 减少到100以下了,那么t3在pthread_cond_wait()返回之后,显然应该再检查一遍sum的大小.这就是用 while的用意。