`
weihe6666
  • 浏览: 440068 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

浅析pthread_cond_wait

    博客分类:
  • UNIX
阅读更多
浅析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的机制可以很好的学习条件变量。


分享到:
评论
2 楼 su6838354 2015-04-29  
我有点疑问啊,thread1中的i自增的慢的话,thread2 会多次执行,时序上存在问题吧
1 楼 zeronever 2012-08-29  
请问pthread_cond_signal有解锁操纵吗?我在pthread_cond_signal后睡眠住1号线程,此时2号线程也没有再执行,这意味着pthread_cond_wait还阻塞着吧

相关推荐

    pthread_cond_wait() 用法深入分析

    `pthread_cond_wait()` 是 POSIX 线程库中的一个关键函数,用于线程同步。它与互斥锁(mutex)一起工作,允许线程在特定条件满足时挂起执行,等待其他线程发出信号。在深入分析 `pthread_cond_wait()` 的用法之前,...

    信号pthread_cond_wait

    《深入理解pthread_cond_wait:多线程同步的关键》 在多线程编程中,线程间的同步至关重要,而`pthread_cond_wait`就是一种用于线程间同步的重要工具,它属于POSIX线程库(pthread)的一部分。这个函数使得一个线程...

    为什么在pthread_cond_wait()前要加一个while循环来判断条件是否为假呢?.Linux 多线程

    在Linux多线程编程中,`pthread_cond_wait()`是一个关键的同步原语,它用于线程间的通信和协作。在使用`pthread_cond_wait()`时,通常会在调用它之前加入一个while循环来判断条件是否满足。这个做法是为了避免虚假...

    Linux多线程之条件阻塞代码

    在这个主题中,我们将深入探讨如何使用互斥锁(mutex)和条件变量(pthread_cond_wait, pthread_cond_signal)来实现线程间的同步和通信,从而解决条件阻塞的问题。 1. **互斥锁(Mutex)** 互斥锁是一种同步机制...

    Linux多线程编程,替代sleep的几种方式

    我只想要进程的某个线程休眠一段时间的,可是用sleep()是将整个进程都休眠的,这个可能达不到,我们想要的效果...  采用pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t *mutex, const struct timesp

    pthread_cond

    通过调用`pthread_cond_wait()`函数,线程可以在等待条件变为真时释放对互斥锁的持有,进入睡眠状态。当其他线程改变了这个条件并调用`pthread_cond_signal()`或`pthread_cond_broadcast()`时,等待的线程会被唤醒,...

    pthread_testcancel pthread_kill pthread_cancel

    pthread_testcancel pthread_kill pthread_cancel 的使用例子

    Posix(1).rar_POSIX Pthread_posix_pthread_pthread posix

    6. **线程间通信**:`pthread_cond_broadcast()`、`pthread_cond_signal()`和`pthread_cond_wait()`等函数用于线程间的通信,协调工作进度。 7. **线程局部存储**:`pthread_key_create()`和`pthread_getspecific()...

    pthreads_pthread_

    5. `pthread_cond_t` 和 `pthread_cond_init() / pthread_cond_wait() / pthread_cond_signal() / pthread_cond_broadcast()`:条件变量,用于线程间通信和同步,当满足特定条件时,一个线程通知其他等待线程。...

    编译时报 Looking for pthread_create - not found 的解决办法

    编译时报 Looking for pthread_create - not found 的解决办法 linux gcc 编译时报Looking for pthread_create - not found 其解决办法是...

    pthread-primer.rar_Pthread Primer pdf_pthread_pthread primer

    create()`用于创建新的线程,`pthread_join()`用于等待线程结束,`pthread_mutex_t`和`pthread_mutex_lock()`、`pthread_mutex_unlock()`用于互斥锁,保证资源的安全访问,`pthread_cond_t`和`pthread_cond_wait()`...

    pthread(arm_linux).zip_ARM Linux_arm_arm linux pthread_arm pthre

    常用函数有`pthread_cond_init()`、`pthread_cond_wait()`和`pthread_cond_signal()`。 3. 信号量:一种计数型同步机制,可以实现线程间的资源控制和同步。`sem_open()`、`sem_post()`和`sem_wait()`等函数用于信号...

    pthread_self获取当前调用线程的识别码

    4. **条件变量**:在使用 `pthread_cond_wait` 和 `pthread_cond_signal` 等条件变量函数时,也需要用到 `pthread_self` 来确定发送信号或等待的线程。 5. **线程退出**:有时,你需要知道哪个线程正在执行特定的...

    Windows可使用的pthread库

    - **条件变量**:允许线程等待某个特定条件满足后再继续执行,例如`pthread_cond_wait`和`pthread_cond_signal`。 - **读写锁**:允许多个线程同时读取共享数据,但只允许一个线程进行写操作,如`pthread_rwlock_...

    2_pthread_sync.tgz

    线程可以使用`pthread_cond_wait`函数等待条件变量,并在条件满足时通过`pthread_cond_signal`或`pthread_cond_broadcast`唤醒等待的线程。条件变量常与互斥锁配合使用,防止信号发送时的数据不一致。 3. **信号量*...

    windows 下的pthread 库

    - **条件变量**(Condition Variable):`pthread_cond_t`表示条件变量,`pthread_cond_init()`和`pthread_cond_destroy()`用于初始化和销毁,`pthread_cond_wait()`和`pthread_cond_signal()`或`pthread_cond_...

    pthread_mutex

    `1_pthread_mutex.tgz`、`1_pthread_mutex`、`1_pthread_deadlock`和`1_pthread_basic`这些文件名可能包含了一些示例代码,比如展示了如何初始化、锁定、解锁互斥锁,以及如何处理可能出现的死锁问题。死锁是指两个...

    [并发并行]_[线程同步]_[pthread_once 实现单例模式分析]

    `pthread_once` 是一个在 POSIX 标准中定义的函数,用于实现线程安全的初始化。在这个场景下,我们将深入探讨如何使用 `pthread_once` 在 C/C++ 中实现单例模式,并结合 `Win32` 平台的特性进行讨论。 首先,单例...

Global site tag (gtag.js) - Google Analytics