浅析pthread_cond_wait
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
一 pthread_cond_wait定义:
函数原型:int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
参数: cond 条件变量 mutex 互斥锁
第一个参数*cond是指向一个条件变量的指针。第二个参数*mutex则是对相关的互斥锁的指针。
二 pthread_cond_wait示例理解
pthread_cond_wait的机制比较难里理解,是条件变量中重要的成分。条件变量用于线程间同步,那么pthread_cond_wait必须和互斥锁同时作用在一个线程里,它同时起到对资源的加锁和解锁,看下面的示例:
程序创建了2个新线程使他们同步运行,实现进程t_b打印9以内3的倍数,t_a打印其他的数,程序开始线程t_b不满足条件等待,线程t_a运行使a循环加1并打印。直到i为3的倍数时,线程t_a发送信号通知进程t_b,这时t_b满足条件,打印i值。
1 #include<pthread.h>
2 #include<unistd.h>
3 #include<stdio.h>
4 #include<stdlib.h>
5
6 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
7 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//init cond
8
9 void *thread1(void*);
10 void *thread2(void*);
11
12 int i = 1; //global
13
14 int main(void){
15 pthread_t t_a;
16 pthread_t t_b;//two thread
17
18 pthread_create(&t_a,NULL,thread2,(void*)NULL);
19 pthread_create(&t_b,NULL,thread1,(void*)NULL);//Create thread
20
21 pthread_join(t_b,NULL);//wait a_b thread end
22 pthread_mutex_destroy(&mutex);
23 pthread_cond_destroy(&cond);
24 exit(0);
25 }
26
27 void *thread1(void *junk){
28 for(i = 1;i<= 9; i++){
29 pthread_mutex_lock(&mutex); //互斥锁
30 printf("call thread1 \n");
31 if(i%3 == 0)
32 pthread_cond_signal(&cond); //send sianal to t_b
33 else
34 printf("thread1: %d\n",i);
35 pthread_mutex_unlock(&mutex);
36 sleep(1);
37 }
38 }
39
40 void *thread2(void*junk){
41 while(i < 9)
42 {
43 pthread_mutex_lock(&mutex);
44 printf("call thread2 \n");
45 if(i%3 != 0)
46 pthread_cond_wait(&cond,&mutex); //wait
47 printf("thread2: %d\n",i);
48 pthread_mutex_unlock(&mutex);
49 sleep(1);
50 }
51 }
输出:
call thread2
call thread1
thread1: 1
call thread1
thread1: 2
call thread1
thread2: 3
call thread1
thread1: 4
call thread2
call thread1
thread1: 5
call thread1
thread2: 6
call thread1
thread1: 7
call thread2
call thread1
thread1: 8
call thread1
thread2: 9
示例的解释:
call thread2:是线程2即t_b首先上锁,即 pthread_mutex_lock(&mutex);锁住了mutex使得此进程执行线程2中的临界区的代码,当执行到45行:if(i%3 != 0),此时i=1,满足此条件,则执行46行: pthread_cond_wait(&cond,&mutex); 这句是关键,pthread_cond_wait(&cond,&mutex)操作有两步,是原子操作:第一 解锁,先解除之前的pthread_mutex_lock锁定的mutex;第二 挂起,阻塞并在等待对列里休眠,即线程2挂起,直到再次被唤醒,唤醒的条件是由pthread_cond_signal(&cond);发出的cond信号来唤醒。
call thread1:由于pthread_cond_wait已经对线程2解锁,此时另外的线程只有线程1,那么线程1对mutex上锁,若这时有多个线程,那么线程间上锁的顺序和操作系统有关。
thread1: 1:线程1上锁后执行临界区的代码,当执行到if(i%3 == 0)此时i=1,不满足条件,则pthread_cond_signal(&cond);不被执行,那么线程2仍处于挂起状态,输出thread1: 1后线程1由pthread_mutex_unlock(&mutex);解锁。
thread1: 2:这时此进程中只有2个线程,线程2处于挂起状态,那么只有线程1,则线程1又对mutex上锁,此时同样执行临界区的代码,而且i=2,不满足条件,pthread_cond_signal(&cond);不被执行,那么线程2仍处于挂起状态,输出thread1: 1后线程1由pthread_mutex_unlock(&mutex);解锁。
call thread1:同样由线程1上锁,但此时i=3,满足条件pthread_cond_signal(&cond)被执行,那么pthread_cond_signal(&cond)会发出信号,来唤醒处于挂起的线程2。pthread_cond_signal同样由两个原子操作:1,解锁;2,发送信号;解锁即对线程1解锁,解除对mutex的上锁。发送信号,即给等待signal挂起的线程2发送信号,唤醒挂起的线程2。
thread2: 3:由于pthread_cond_signal唤醒了线程2,即i=3满足条件,pthread_cond_wait(&cond,&mutex);被执行,那么pthread_cond_wait(&cond,&mutex)此时也有一步操作:上锁;即对线程2上锁,此时的pthread_cond_wait(&cond,&mutex)的操作相当与pthread_mutex_lock(&mutex);那么线程2继续执行上锁后的临界区的代码,并由pthread_mutex_unlock(&mutex);对线程2进行解锁。
剩下的输出原理和上面解释的一样。
纵观pthread_cond_wait,它的理解不可之把它看作一个简单的wait函数,它里面应该是一族函数,不同的函数在不同的条件下执行,理解pthread_cond_wait的机制可以很好的学习条件变量。
分享到:
相关推荐
`pthread_cond_wait()` 是 POSIX 线程库中的一个关键函数,用于线程同步。它与互斥锁(mutex)一起工作,允许线程在特定条件满足时挂起执行,等待其他线程发出信号。在深入分析 `pthread_cond_wait()` 的用法之前,...
《深入理解pthread_cond_wait:多线程同步的关键》 在多线程编程中,线程间的同步至关重要,而`pthread_cond_wait`就是一种用于线程间同步的重要工具,它属于POSIX线程库(pthread)的一部分。这个函数使得一个线程...
在Linux多线程编程中,`pthread_cond_wait()`是一个关键的同步原语,它用于线程间的通信和协作。在使用`pthread_cond_wait()`时,通常会在调用它之前加入一个while循环来判断条件是否满足。这个做法是为了避免虚假...
在这个主题中,我们将深入探讨如何使用互斥锁(mutex)和条件变量(pthread_cond_wait, pthread_cond_signal)来实现线程间的同步和通信,从而解决条件阻塞的问题。 1. **互斥锁(Mutex)** 互斥锁是一种同步机制...
我只想要进程的某个线程休眠一段时间的,可是用sleep()是将整个进程都休眠的,这个可能达不到,我们想要的效果... 采用pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t *mutex, const struct timesp
通过调用`pthread_cond_wait()`函数,线程可以在等待条件变为真时释放对互斥锁的持有,进入睡眠状态。当其他线程改变了这个条件并调用`pthread_cond_signal()`或`pthread_cond_broadcast()`时,等待的线程会被唤醒,...
pthread_testcancel pthread_kill pthread_cancel 的使用例子
6. **线程间通信**:`pthread_cond_broadcast()`、`pthread_cond_signal()`和`pthread_cond_wait()`等函数用于线程间的通信,协调工作进度。 7. **线程局部存储**:`pthread_key_create()`和`pthread_getspecific()...
5. `pthread_cond_t` 和 `pthread_cond_init() / pthread_cond_wait() / pthread_cond_signal() / pthread_cond_broadcast()`:条件变量,用于线程间通信和同步,当满足特定条件时,一个线程通知其他等待线程。...
编译时报 Looking for pthread_create - not found 的解决办法 linux gcc 编译时报Looking for pthread_create - not found 其解决办法是...
create()`用于创建新的线程,`pthread_join()`用于等待线程结束,`pthread_mutex_t`和`pthread_mutex_lock()`、`pthread_mutex_unlock()`用于互斥锁,保证资源的安全访问,`pthread_cond_t`和`pthread_cond_wait()`...
常用函数有`pthread_cond_init()`、`pthread_cond_wait()`和`pthread_cond_signal()`。 3. 信号量:一种计数型同步机制,可以实现线程间的资源控制和同步。`sem_open()`、`sem_post()`和`sem_wait()`等函数用于信号...
4. **条件变量**:在使用 `pthread_cond_wait` 和 `pthread_cond_signal` 等条件变量函数时,也需要用到 `pthread_self` 来确定发送信号或等待的线程。 5. **线程退出**:有时,你需要知道哪个线程正在执行特定的...
- **条件变量**:允许线程等待某个特定条件满足后再继续执行,例如`pthread_cond_wait`和`pthread_cond_signal`。 - **读写锁**:允许多个线程同时读取共享数据,但只允许一个线程进行写操作,如`pthread_rwlock_...
线程可以使用`pthread_cond_wait`函数等待条件变量,并在条件满足时通过`pthread_cond_signal`或`pthread_cond_broadcast`唤醒等待的线程。条件变量常与互斥锁配合使用,防止信号发送时的数据不一致。 3. **信号量*...
- **条件变量**(Condition Variable):`pthread_cond_t`表示条件变量,`pthread_cond_init()`和`pthread_cond_destroy()`用于初始化和销毁,`pthread_cond_wait()`和`pthread_cond_signal()`或`pthread_cond_...
`1_pthread_mutex.tgz`、`1_pthread_mutex`、`1_pthread_deadlock`和`1_pthread_basic`这些文件名可能包含了一些示例代码,比如展示了如何初始化、锁定、解锁互斥锁,以及如何处理可能出现的死锁问题。死锁是指两个...
`pthread_once` 是一个在 POSIX 标准中定义的函数,用于实现线程安全的初始化。在这个场景下,我们将深入探讨如何使用 `pthread_once` 在 C/C++ 中实现单例模式,并结合 `Win32` 平台的特性进行讨论。 首先,单例...