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

条件变量与互斥锁不同,条件变量是⽤来等待⽽不是⽤来上锁的。
条件变量⽤来⾃动阻塞⼀个线程,直到某特殊情况发⽣为⽌。
通常条件变量和互斥锁同时使⽤。
条件变量使我们可以睡眠等待某种条件出现。
条件变量是利⽤线程间共享的全局变量进⾏同步的⼀种机制,主要包括两个动作:⼀个线程等待"条件变量的条件成⽴"⽽挂起;另⼀个线程使"条件成⽴"(给出条件成⽴信号)。
条件的检测是在互斥锁的保护下进⾏的。
如果⼀个条件为假,⼀个线程⾃动阻塞,并释放等待状态改变的互斥锁。
如果另⼀个线程改变了条件,它发信号给关联的条件变量,唤醒⼀个或多个等待它的线程,重新获得互斥锁,重新评价条件。
如果两进程共享可读写的内存,条件变量可以被⽤来实现这两进程间的线程同步。
使⽤条件变量之前要先进⾏初始化。
可以在单个语句中⽣成和初始化⼀个条件变量如: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)消息队列是一种用于线程间通信的机制,可以实现线程之间的消息传递和异步通信。
消息队列通过一个先进先出的队列,将消息从发送者传递到接收者。
发送者将消息放入队列中,接收者从队列中取出消息并进行处理。
消息队列可以实现线程之间的解耦和异步通信。
总结:多线程下的消息机制是实现线程间通信和交流的重要机制,它可以实现线程之间的同步和互斥访问,保证共享资源的安全性,同时也可以实现线程之间的解耦和异步通信。
不同的消息机制适用于不同的场景和需求,开发人员需要根据具体情况选择合适的消息机制来实现线程之间的通信。
操作系统中的信号量、互斥锁与条件变量

操作系统中的信号量、互斥锁与条件变量在操作系统领域,信号量、互斥锁和条件变量是常用的同步机制,用于控制多个线程或进程之间的访问和操作。
本文将介绍它们的概念、原理和应用。
一、信号量(Semaphore)信号量是一个用于多线程或多进程之间同步的计数器。
它通常用于限制共享资源的访问数量,防止多个线程或进程同时访问造成竞态条件(Race Condition)。
信号量可以控制并发的访问和修改共享资源的数量,提高系统的安全性和稳定性。
信号量有两种类型:二进制信号量(Binary Semaphore)和计数信号量(Counting Semaphore)。
二进制信号量只有两种状态,即0和1,用于互斥访问共享资源,实现临界区的互斥。
计数信号量可以有多个状态,用于控制访问共享资源的数量,实现资源的同步访问。
在使用信号量时,线程或进程可以通过P操作(等待信号量)和V 操作(发信号量)来控制资源的访问。
当线程或进程试图访问共享资源时,需要执行P操作来减少信号量的计数器。
如果信号量的计数器已经为0,则线程或进程将被阻塞,直到计数器变为正数才能继续执行。
当线程或进程访问完共享资源后,需要执行V操作来增加信号量的计数器,以便其他线程或进程可以继续访问共享资源。
二、互斥锁(Mutex)互斥锁是一种常用的同步机制,用于保护共享资源的访问,确保同一时间只有一个线程可以访问共享资源。
互斥锁提供了独占访问共享资源的能力,避免了竞态条件的发生。
互斥锁的使用非常简单,线程在访问共享资源之前需要先获取锁,访问完成后再释放锁。
当一个线程获取到锁时,其他线程将被阻塞,直到锁被释放为止。
互斥锁可以保证共享资源的互斥访问,从而保证数据的一致性和完整性。
互斥锁主要通过两个操作来实现:加锁操作(Lock)和解锁操作(Unlock)。
当一个线程执行加锁操作时,如果锁已经被其他线程占用,则该线程将被阻塞。
解锁操作用于释放锁,使得其他线程可以获取到锁。
三、条件变量(Condition Variable)条件变量是一种用于线程之间同步的工具,它允许线程按照一定的条件等待和唤醒。
c语言 互斥锁 信号量 条件变量

C语言中的互斥锁、信号量和条件变量1. 介绍C语言作为一种广泛应用的程序设计语言,其在多线程编程中也有着重要的作用。
在多线程编程中,为了保证线程之间的同步和互斥操作,常常需要使用互斥锁、信号量和条件变量等机制。
本文将对C语言中的互斥锁、信号量和条件变量进行介绍,以帮助读者更好地理解和应用这些关键的多线程编程工具。
2. 互斥锁互斥锁是一种常用的线程同步工具,用于保护共享资源不被多个线程同时访问。
在C语言中,我们可以使用pthread库中的mutex来实现互斥锁。
互斥锁的基本操作包括初始化、上锁和解锁。
具体代码如下:```c#include <pthread.h>pthread_mutex_t mutex;int m本人n() {pthread_mutex_init(mutex, NULL);// 上锁pthread_mutex_lock(mutex);// 访问共享资源// 解锁pthread_mutex_unlock(mutex);pthread_mutex_destroy(mutex);return 0;}```通过使用互斥锁,可以有效防止多个线程同时访问共享资源而造成的数据竞争问题,保证了程序的正确性和可靠性。
3. 信号量信号量是另一种常用的线程同步工具,用于实现线程间的互斥和同步操作。
在C语言中,我们可以使用pthread库中的semaphore来实现信号量。
信号量的基本操作包括初始化、等待和释放。
具体代码如下:```c#include <pthread.h>#include <semaphore.h>sem_t sem;int m本人n() {sem_init(sem, 0, 1);// 等待sem_w本人t(sem);// 访问共享资源// 释放sem_post(sem);sem_destroy(sem);return 0;}```通过使用信号量,可以控制多个线程对共享资源的访问顺序,从而避免出现竞争条件和死锁等问题,确保程序的正确执行。
线程同步(信号量,互斥,条件变量)

线程同步(信号量,互斥,条件变量)收藏进行多线程编程,最头疼的就是那些共享的数据。
因为你无法知道哪个线程会在哪个时候对它进行操作,你也无法得知那个线程会先运行,哪个线程会后运行。
下面介绍一些技术,通过他们,你会合理安排你的线程之间对资源的竞争。
l 互斥量Mutexl 信号灯Semophorel 条件变量Conditions先说一下互斥量。
什么时候会用上互斥量了?比如你现在有一全局链表,你有几个工作线程。
每一个线程从该链表中取出头节点,然后对该头节点进行处理。
比如现在线程1正在取出头节点,他的操作如下:Item * p =queue_list;Queue_list=queue_list->next;Process_job(p);Free(p);当线程1处理完第一步,也就是Item *p=queue_list后,这时候系统停止线程1的运行,改而运行线程2。
线程2照样取出头节点,然后进行处理,最后释放了该节点。
过了段时间,线程1重新得到运行。
而这个时候,其实p所指向的节点已经被线程2释放掉,而线程1对此毫无知晓。
他会接着运行process_job(p)。
而这将导致无法预料的后果!对于这种情况,系统给我们提供了互斥量。
你在取出头节点前必须要等待互斥量,如果此时有其他线程已经获得该互斥量,那么线程将会阻塞在这个地方。
只有等到其他线程释放掉该互斥量后,你的线程才有可能得到该互斥量。
为什么是可能了?因为可能此时有不止你一个线程在等候该互斥量,而系统无法保证你的线程将会优先运行。
互斥量的类型为pthread_mutex_t。
你可以声明多个互斥量。
在声明该变量后,你需要调用pthread_mutex_init()来创建该变量。
pthread_mutex_init的格式如下:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex-attr_t *mutexattr);第一个参数,mutext,也就是你之前声明的那个互斥量,第二个参数为该互斥量的属性。
互斥锁、信号量、条件变量的区别

互斥锁、信号量、条件变量的区别来⾃:信号量⽤在多线程多任务同步的,⼀个线程完成了某⼀个动作就通过信号量告诉别的线程,别的线程再进⾏某些动作(⼤家都在semtake的时候,就阻塞在哪⾥)。
⽽互斥锁是⽤在多线程多任务互斥的,⼀个线程占⽤了某⼀个资源,那么别的线程就⽆法访问,直到这个线程unlock,其他的线程才开始可以利⽤这个资源。
⽐如对全局变量的访问,有时要加锁,操作完了,在解锁。
有的时候锁和信号量会同时使⽤的”也就是说,信号量不⼀定是锁定某⼀个资源,⽽是流程上的概念,⽐如:有A,B两个线程,B线程要等A线程完成某⼀任务以后再进⾏⾃⼰下⾯的步骤,这个任务并不⼀定是锁定某⼀资源,还可以是进⾏⼀些计算或者数据处理之类。
⽽线程互斥量则是“锁住某⼀资源”的概念,在锁定期间内,其他线程⽆法对被保护的数据进⾏操作。
在有些情况下两者可以互换。
两者之间的区别:作⽤域信号量: 进程间或线程间(linux仅线程间)互斥锁: 线程间上锁时信号量: 只要信号量的value⼤于0,其他线程就可以sem_wait成功,成功后信号量的value减⼀。
若value值不⼤于0,则sem_wait阻塞,直到sem_post释放后value值加⼀互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源成功后否则就阻塞以下是信号灯(量)的⼀些概念:信号灯与互斥锁和条件变量的主要不同在于”灯”的概念,灯亮则意味着资源可⽤,灯灭则意味着不可⽤。
如果说后两中同步⽅式侧重于”等待”操作,即资源不可⽤的话,信号灯机制则侧重于点灯,即告知资源可⽤;没有等待线程的解锁或激发条件都是没有意义的,⽽没有等待灯亮的线程的点灯操作则有效,且能保持灯亮状态。
当然,这样的操作原语也意味着更多的开销。
信号灯的应⽤除了灯亮/灯灭这种⼆元灯以外,也可以采⽤⼤于1的灯数,以表⽰资源数⼤于1,这时可以称之为多元灯。
1.创建和注销POSIX信号灯标准定义了有名信号灯和⽆名信号灯两种,但LinuxThreads的实现仅有⽆名灯,同时有名灯除了总是可⽤于多进程之间以外,在使⽤上与⽆名灯并没有很⼤的区别,因此下⾯仅就⽆名灯进⾏讨论。
信号量和条件变量的异同点

信号量和条件变量的异同点信号量和条件变量是操作系统中常用的同步机制,它们都可以用于线程间的通信和协调,但在实际应用中有着不同的特点和用途。
本文将从异同点的角度来探讨信号量和条件变量的区别。
我们先来看看信号量。
信号量是一种用于控制多个线程对共享资源的访问的同步原语。
它通常用于实现互斥访问和同步操作。
信号量可以是二进制的,也可以是计数型的。
二进制信号量只有两种状态:0和1,通常用于实现互斥锁;而计数型信号量可以有多个取值,用于表示共享资源的数量或可用资源的数量。
通过对信号量的操作,可以实现线程的阻塞和唤醒,从而实现线程的同步。
与信号量不同,条件变量是一种线程间的通信机制,它通常用于在线程间传递信号或通知。
条件变量总是与互斥锁一起使用,它提供了一种等待通知的机制,当某个条件不满足时,线程可以进入等待状态,直到其他线程发送信号通知它条件已经满足。
条件变量通常用于实现生产者-消费者模型或读者-写者模型等场景。
在使用上,信号量主要用于保护共享资源的访问,通过对信号量进行P操作(等待)和V操作(释放),可以控制线程对共享资源的访问顺序和数量。
而条件变量主要用于线程间的通信,通过对条件变量的等待和通知操作,可以实现线程间的协作和同步。
信号量和条件变量在实现上也有一些不同之处。
信号量可以由用户自定义的计数器来表示可用资源的数量,通过对计数器的操作来控制线程的访问;而条件变量通常与互斥锁一起使用,等待和通知的操作需要在互斥锁的保护下进行,以确保线程安全。
总的来说,信号量和条件变量都是重要的同步机制,它们在不同的场景下有着不同的作用和用途。
信号量主要用于控制资源的访问和同步操作,而条件变量主要用于线程间的通信和协作。
在实际应用中,可以根据具体的需求选择合适的同步机制来实现线程间的通信和协调,以提高程序的效率和可靠性。
互斥锁 信号量 条件变量

互斥锁信号量条件变量互斥锁、信号量和条件变量是解决多线程竞争问题的三种常用技术。
互斥锁是一种互斥量,用于保护共享资源的访问。
在多线程环境中,如果不进行互斥控制,多个线程有可能同时访问共享资源,导致数据出现不一致或程序崩溃的情况。
互斥锁能够确保只有一个线程可以访问共享资源,其他线程需要等待该线程释放互斥锁后才能继续访问。
在Linux系统下,互斥锁的实现是通过pthread_mutex_t结构体来实现的。
信号量是一种同步原语,也可以用于互斥控制和进程间通信。
信号量主要有两种类型:二进制信号量和计数信号量。
二进制信号量只有两种状态,0和1,通常用于锁机制。
计数信号量有一个初始值,并且可以被线程递增或递减。
当一个线程想要访问共享资源时,它通过调用sem_wait()函数来减少信号量的值,如果信号量的值变为0,则表示共享资源已经被占用,并且该线程需要等待其他线程释放信号量才能继续执行。
在Linux系统下,信号量的实现是通过sem_t结构体来实现的。
条件变量是一种线程间通信机制,它允许线程被阻塞,直到某个特定的条件被触发。
条件变量通常与互斥锁一起使用来实现线程同步。
在Linux系统下,条件变量的实现是通过pthread_cond_t结构体来实现的。
三种技术的最大区别在于它们的使用场景。
互斥锁用于保护共享资源的互斥访问,信号量用于控制并发线程的数量,而条件变量用于同步线程的执行顺序。
因此,在编写多线程程序时,需要根据实际情况选择合适的同步机制。
此外,如果多个线程需要访问共享资源,并且需要保证线程之间的竞争不会导致数据不一致或程序崩溃的情况发生,那么互斥锁是最好的选择。
如果需要控制并发线程数量,则可以使用信号量,如果需要同步线程的执行顺序,则可以使用条件变量。
总而言之,互斥锁、信号量和条件变量是解决多线程竞争问题的三种常用技术。
在编写多线程程序时,应该根据实际情况选择合适的同步机制,以确保程序的正确性和性能。
Linux互斥锁、条件变量和信号量

Linux--Linux互斥锁、条件变量和信号量进行多线程编程,最应该注意的就是那些共享的数据,因为无法知道哪个线程会在哪个时候对它进行操作,也无法得知哪个线程会先运行,哪个线程会后运行。
所以,要对这些资源进行合理的分配和正确的使用。
在Linux下,提供了互斥锁、条件变量和信号量来对共享资源进行保护。
一、互斥锁互斥锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源。
需要的头文件:pthread.h互斥锁标识符:pthread_mutex_t(1)互斥锁初始化:函数原型:int pthread_mutex_init (pthread_mutex_t* mutex,const pthread_mutexattr_t* mutexattr);函数传入值:mutex:互斥锁。
mutexattr:PTHREAD_MUTEX_INITIALIZER 创建快速互斥锁。
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 创建递归互斥锁。
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 创建检错互斥锁。
函数返回值:成功:0;出错:-1(2)互斥操作函数int pthread_mutex_lock(pthread_mutex_t* mutex); //上锁int pthread_mutex_trylock (pthread_mutex_t* mutex); //只有在互斥被锁住的情况下才阻塞int pthread_mutex_unlock (pthread_mutex_t* mutex); //解锁int pthread_mutex_destroy (pthread_mutex_t* mutex); //清除互斥锁函数传入值:mutex:互斥锁。
函数返回值:成功:0;出错:-1使用形式:pthread_mutex_t mutex;pthread_mutex_init (&mutex, NULL); /*定义*/...pthread_mutex_lock(&mutex); /*获取互斥锁*/... /*临界资源*/pthread_mutex_unlock(&mutex); /*释放互斥锁*/备注:互斥锁MUTEX的使用注意lock和unlock的配对使用,否则容易出现死锁发生。
linux系统的各类同步机制

linux系统的各类同步机制在Linux系统中,有多种同步机制可用于保护共享资源和控制并发访问。
以下是几种常见的同步机制:1. 互斥锁(Mutex):互斥锁用于确保在同一时间只有一个线程可以访问被保护的资源。
线程在进入临界区之前会尝试获取互斥锁,如果锁已经被其他线程持有,则线程会被阻塞,直到锁被释放。
2. 读写锁(ReadWrite Lock):读写锁允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。
这种机制能够提高并发性能,因为多个线程可以同时读取资源而无需互斥。
3. 条件变量(Condition Variable):条件变量允许线程在某个条件满足时进入等待状态,直到其他线程通知条件变量。
条件变量通常与互斥锁一起使用,以确保在等待条件时不会发生竞争条件。
4. 信号量(Semaphore):信号量用于控制对有限资源的访问。
它可以允许多个线程同时访问资源,但在资源耗尽时会阻塞后续线程,直到有可用资源为止。
5. 屏障(Barrier):屏障用于保证多个线程在达到某个点之前都会等待,然后同时继续执行。
它通常用于同步多个线程的执行顺序,确保某些依赖关系的操作在其他操作之前完成。
6. 读-写自旋锁(Read-Write Spinlock):读-写自旋锁类似于读写锁,但不使用互斥锁或条件变量。
它使用自旋等待来避免线程的上下文切换开销,适用于并发读取操作非常频繁而写入操作相对较少的情况。
7. 自旋锁(Spinlock):自旋锁类似于互斥锁,但线程在无法获取锁时不会进入睡眠状态,而是进行忙等待。
自旋锁适用于临界区的保护时间非常短暂,线程不希望被睡眠和唤醒所带来的开销。
这些同步机制在Linux系统中被广泛使用,用于保护共享资源的一致性和正确性,并控制并发访问共享资源的顺序。
不同的场景和需求可能需要选择不同的同步机制来达到最佳性能和效果。
四种进程或线程同步互斥的控制方法

四种进程或线程同步互斥的控制方法进程或线程的同步与互斥是计算机操作系统中重要的概念,用于控制多个进程或线程之间的访问共享资源。
下面将介绍四种常用的进程或线程同步互斥的控制方法。
1. 互斥锁(Mutex):互斥锁是最常用的同步互斥控制方法之一、当一些进程或线程获得了互斥锁后,其他进程或线程就无法获得该锁,只能等待锁的释放。
只有当获得互斥锁的进程或线程执行完毕后,才能释放锁,让其他进程或线程继续执行。
这种方式可以有效避免多个进程或线程同时访问共享资源而导致的冲突。
2. 信号量(Semaphore):信号量是一种更加复杂的同步互斥控制方法。
信号量可以通过一个整型变量值来表示可用资源的数量。
当一个进程或线程需要访问共享资源时,首先会尝试获取信号量。
如果信号量的值大于0,则获取成功,可以继续执行;如果信号量的值等于0,则获取失败,进程或线程需要阻塞等待其他进程或线程释放信号量。
当进程或线程完成对共享资源的访问后,会释放信号量,使得其他进程或线程可以获取到它。
3. 条件变量(Condition Variable):条件变量是一种比较高级的同步互斥控制方法。
条件变量不是用来保护共享资源的访问的,而是用来等待其中一种条件的发生。
当一个进程或线程需要等待其中一种条件满足时,会通过条件变量进行阻塞。
当条件满足后,其他进程或线程可以通过条件变量发送信号来唤醒等待的进程或线程。
4. 屏障(Barrier):屏障是一种用于同步多个进程或线程的控制方法。
屏障会将进程或线程分为多个阶段,并在每个阶段结束时设置一个屏障。
当一个进程或线程到达屏障时,它会阻塞等待其他进程或线程到达。
只有当所有进程或线程都到达了屏障,才会释放它们,继续执行下一个阶段。
屏障可以用于控制多个任务的执行顺序,保证它们在一定时刻到达同一个点。
这四种方法都是常见的进程或线程同步互斥的控制方法,每种方法都有自己的适用场景和实现方式。
根据具体的应用需求和系统架构,可以选择合适的方法来实现进程或线程的同步与互斥。
线程互斥的几种方式

线程互斥的几种方式
线程互斥是指多个线程在访问共享资源时,需要进行同步操作,以避免出现冲突和数据损坏。
以下是几种常见的线程互斥方式:
1. 互斥锁:通过互斥锁来实现线程互斥。
当一个线程获得了互
斥锁,其他线程就不能获得该锁,只能等待当前线程释放锁。
常见的互斥锁包括pthread_mutex_t和std::mutex。
2. 信号量:信号量是一种更加通用的同步原语,它可以用于实
现线程互斥和线程同步。
当一个线程获得了信号量,其他线程就不能获得该信号量,只能等待当前线程释放信号量。
常见的信号量包括pthread_cond_t和std::condition_variable。
3. 读写锁:读写锁允许多个线程同时读取共享资源,但是只允
许一个线程进行写操作。
通过这种方式来提高程序的并发性能。
常见的读写锁包括pthread_rwlock_t和std::shared_mutex。
4. 原子操作:原子操作是一种不可分割的操作,可以保证多个
线程对共享变量进行操作时的同步性。
常见的原子操作包括
std::atomic和__sync_fetch_and_add。
5. 条件变量:条件变量是一种线程同步机制,可以在多个线程
之间传递信息,用于线程之间的通信。
当一个线程等待条件变量时,它会进入睡眠状态,直到另一个线程发出信号通知它。
常见的条件变量包括pthread_cond_t和std::condition_variable。
以上是几种常见的线程互斥方式,不同的方式适用于不同的场景,开发者需要根据具体情况选择适合的方式。
信号量和互斥量

信号量与互斥锁信号量与普通整型变量的区别:①信号量(semaphore)是非负整型变量,除了初始化之外,它只能通过两个标准原子操作:wait(semap) , signal(semap) ; 来进行访问;②操作也被成为PV原语(P来源于Dutch proberen"测试",V来源于Dutch verhogen"增加"),而普通整型变量则可以在任何语句块中被访问;信号量与互斥锁之间的区别:1. 互斥量用于线程的互斥,信号线用于线程的同步。
这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。
但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。
在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。
少数情况是指可以允许多个访问者同时访问资源2. 互斥量值只能为0/1,信号量值可以为非负整数。
也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。
信号量可以实现多个同类资源的多线程互斥和同步。
当信号量为单值信号量是,也可以完成一个资源的互斥访问。
3. 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。
信号量信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
信号量可以分为几类:²二进制信号量(binary semaphore):只允许信号量取0或1值,其同时只能被一个线程获取。
²整型信号量(integer semaphore):信号量取值是整数,它可以被多个线程同时获得,直到信号量的值变为0。
²记录型信号量(record semaphore):每个信号量s除一个整数值value(计数)外,还有一个等待队列List,其中是阻塞在该信号量的各个线程的标识。
互斥锁、读写锁、条件变量、信号量的理解

互斥锁、读写锁、条件变量、信号量的理解互斥锁互斥锁:所有操作者地位等价,所有操作共享资源的⽅式在地位上是等价的,实现共享资源任意操作的同步。
/*互斥量的类型 pthread_mutex_tint pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);- 初始化互斥量- 参数:- mutex :需要初始化的互斥量变量- attr :互斥量相关的属性,NULL- restrict : C语⾔的修饰符,被修饰的指针,不能由另外的⼀个指针进⾏操作。
pthread_mutex_t *restrict mutex = xxx;pthread_mutex_t * mutex1 = mutex;int pthread_mutex_destroy(pthread_mutex_t *mutex);- 释放互斥量的资源int pthread_mutex_lock(pthread_mutex_t *mutex);- 加锁,阻塞的,如果有⼀个线程加锁了,那么其他的线程只能阻塞等待int pthread_mutex_trylock(pthread_mutex_t *mutex);- 尝试加锁,如果加锁失败,不会阻塞,会直接返回。
int pthread_mutex_unlock(pthread_mutex_t *mutex);- 解锁*/#include <stdio.h>#include <pthread.h>#include <unistd.h>// 全局变量,所有的线程都共享这⼀份资源。
int tickets = 1000;// 创建⼀个互斥量pthread_mutex_t mutex;void * sellticket(void * arg) {// 卖票while(1) {// 加锁pthread_mutex_lock(&mutex);if(tickets > 0) {usleep(6000);printf("%ld 正在卖第 %d 张门票\n", pthread_self(), tickets);tickets--;}else {// 解锁pthread_mutex_unlock(&mutex);break;}// 解锁pthread_mutex_unlock(&mutex);}return NULL;}int main() {// 初始化互斥量pthread_mutex_init(&mutex, NULL);// 创建3个⼦线程pthread_t tid1, tid2, tid3;pthread_create(&tid1, NULL, sellticket, NULL);pthread_create(&tid2, NULL, sellticket, NULL);pthread_create(&tid3, NULL, sellticket, NULL);// 回收⼦线程的资源,阻塞pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_join(tid3, NULL);pthread_exit(NULL); // 退出主线程// 释放互斥量资源pthread_mutex_destroy(&mutex);return 0;}读写锁读写锁:所有操作者地位等价,所有操作共享资源的⽅式是不等价的,且只划分成了两种地位的操作形式,⼀种是读操作,⼀种是写操作。
- 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的用意。