浅谈条件变量

谈到条件变量,首先需要说到互斥锁。互斥变量比较容易理解:在多线程编程中,经常会发生多个线程对同一个静态变量或者全局变量进行访问,又或者对同一代码区进行访问,这样容易出现问题。所以需要互斥锁,在访问这些变量或者代码区之前首先获取对应的互斥锁,如果互斥锁已经被别的线程获取,那么申请获取互斥锁的线程会被阻塞。

#include <pthread.h>
int n;
//静态分配的互斥量要用PTHREAD_MUTEX_INITIALIZER初始化,共享内存中
//分配的互斥锁需要使用pthread_mutext_init()来初始化。
pthread_mutex_t n_mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&n_mutex);
n++;
pthread_mutex_unlock(&n_mutext);    

考虑有下面应用场景:我们有一段代码区,只有当某个静态变量符合某个条件是才能进入,这个过程不断的循环,另外该静态变量可能会被其他线程修改。

int n;
while (true) {
    if (test(n)) {
        dosomething(n);
    }
}

我们很容易想都用互斥锁来解决该问题。首先申请该静态变量的互斥锁,然后test该变量是否满足条件,如果符合就进入代码区,最后释放互斥锁。

#include <pthread.h>
int n;
pthread_mutex_t n_mutex;
while (true) {
    pthread_mutex_lock(&n_mutex);
    if (test(n)) {
        dosomething(n);
    }
    pthread_mutex_unlock(&n_mutext);
}

这样从可行性方面来说是没问题,但是效率却不好:因为while循环中需要不断的申请互斥锁,然后test变量n,如果为false就直接释放锁。很多情况下,两个test之间其他线程并没有修改n,那么两次test结果一样,如果都为false,那么后一次test是无用功。考虑如果大部分时间n不会被修改,那么while循环就会不断的做申请锁释放锁的无用功。这种方法叫轮询,相当耗费CPU时间。
而条件变量就是用来解决这种情况,他会让线程睡眠,直到某个线程通知他事件发生时他才醒来。通常条件变量会结合互斥锁来使用。互斥锁提供互斥机制,条件变量 提供信号机制。

#include <pthread.h>
int n;
pthread_mutex_t n_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t n_cond = PTHREAD_COND_INITIALIZER;

while (true) {
    pthread_mutex_lock(&n_mutex);
    while (!test(n)) 
        pthread_cond_wait(&n_cond, &n_mutext);

    dosomething(n);
    pthread_mutex_unlock(&n_mutext);
}
pthread_mutex_lock(&n_mutex);
n++;
//通知其他进程
pthread_cond_signal(&n_cond);
pthread_mutex_unlock(&n_mutex);

pthread_cond_wait(&n_cond, &n_mutext)会让线程进入睡眠并且释放所持有的互斥锁,当线程收到通知醒来是就会重新获取互斥锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值