cond 使用介绍

文章目录


一、cond 介绍

cond 的使用总是和互斥锁及共享资源联系在一起的。线程首先锁住互斥锁,然后检验共享资源的状态是否处于可使用的状态。如果不是,那么线程就要等待条件变量。要指向这样的操作就必须在等待的时候将互斥锁解锁,以便其他线程可以访问共享资源并改变其状态

二、cond 基本函数

1. int pthread_cond_init(pthread_cond_t *cv, const pthread_condattr_t *cattr);

初始化一个条件变量,当参数cattr为空指针时,创建的是一个缺省的条件变量
可以用宏 pthread_cond_t cv = PTHREAD_COND_INITIALIZER; 来初始化条件变量,使其具有缺省属性

2. int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex);

  1. 当前线程1在wait内部释放互斥锁,然后阻塞等待条件变量,等待其它线程调用pthread_cond_signal/pthread_cond_broadcast 函数将自己唤醒
  2. 线程2获取到互斥锁(a步wai内部释放了互斥锁),调用pthread_cond_signal/pthread_cond_broadcast 唤醒阻塞等待条件变量的线程1
  3. 线程1被signal唤醒后,wait内部重新获取互斥锁,但此时线程2还没有释放互斥锁,因此线程1被唤醒后继续阻塞等待获取互斥锁
  4. 线程2调用signal后继续执行count++,然后释放互斥锁
  5. 线程1获取到互斥锁(d步线程2释放了互斥锁),wait函数返回,继续往下执行counter–,然后释放互斥锁

3. int pthread_cond_signal(pthread_cond_t *cv);

释放被阻塞在条件变量上的一个线程,如果没有线程被阻塞在条件变量上,那么调用pthread_cond_signal() 将没有作用

4. int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mp, const structtimespec * abstime);

函数到了一定的时间,即使条件未发生也会解除阻塞

5. int pthread_cond_broadcast(pthread_cond_t *cv);

唤醒所有被 pthread_cond_wait 函数阻塞在条件变量上的线程。当没有线程阻塞在这个条件变量上时,pthread_cond_broadcast 函数无效。由于 pthread_cond_broadcast 函数唤醒所有阻塞在条件变量上的线程,这些线程被唤醒后将再次竞争互斥锁(wait函数b步)

6. int pthread_cond_destroy(pthread_cond_t *cv);

释放条件变量

三、cond 使用示例

#include <unistd.h>
#include <pthread.h>
#include <iostream>
using namespace std;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int variable = 0;

void* consumer(void* arg)
{
    int num = *((int*)arg);
    while (1)
    {
        pthread_mutex_lock(&mutex);
        while (variable == 0)
        {
            cout << "consumer " << num << " begin wait condition" << endl;
            pthread_cond_wait(&cond, &mutex); // unlock mutex, blocked on cond
        }
        cout << "consumer " << num << " end wait condition" << endl;
        cout << "consumer " << num << " consume product" << endl;
        variable--;
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
    return NULL;
}

void* producer(void* arg)
{
    while (1)
    {
        pthread_mutex_lock(&mutex);
        variable++;
        pthread_cond_signal(&cond); // wakeup threads waiting on cond
        cout << "producer signal consumer by condition variable" << endl;
        pthread_mutex_unlock(&mutex);
        sleep(3);
    }
    return NULL;
}

int main(void)
{
    pthread_t threads[3];

    for (int i = 0; i < 2; i++)
    {
        pthread_create(&threads[i], NULL, consumer, (void*)&i);
    }
    sleep(1);
    pthread_create(&threads[2], NULL, producer, NULL);
    for (int i = 0; i < 3; i++)
    {
        pthread_join(threads[i], NULL);
    }

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
}

cond 使用介绍

上一篇:Linux多线程及线程同步


下一篇:AfxBeginThread、AfxEndThread、GetExitCodeThread的配合使用