线程安全之条件变量

2022-10-06  本文已影响0人  二进制人类

相关API

初始化

#include <pthread.h>
/**
 * [pthread_cond_init 初始化条件变量]
 * @param  cond [初始化的条件变量指针]
 * @param  attr [要初始化条件变量的属性,使用NULL表示采用默认属性]
 * @return      [成功返回0,失败返回错误号]
 */
int pthread_cond_init(pthread_cond_t *restrict cond,
           const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

销毁

#include <pthread.h>
/**
 * [pthread_cond_destroy 销毁条件变量]
 * @param  cond [指向需要销毁的条件变量指针]
 * @return      [成功返回0,失败返回错误号]
 */
int pthread_cond_destroy(pthread_cond_t *cond);

等待条件

#include <pthread.h>
/**
 * [pthread_cond_wait 
 * 等待一个条件变量
    1) 阻塞等待条件变量cond满足;
    2) 释放已掌握的互斥锁(解锁互斥量)相当于pthread_mutex_unlock(&mutex);
        1) 2) 两步为一个原子操作。
    3) 当被唤醒,pthread_cond_wait函数返回时,解除阻塞并重新申请获取互斥锁pthread_mutex_lock(&mutex);
 * ]
 * @param  cond  [已经初始化的条件变量]
 * @param  mutex [表示互斥锁]
 * @return       [成功返回0,失败返回错误号]
 */
int pthread_cond_wait(pthread_cond_t *restrict cond,
           pthread_mutex_t *restrict mutex);

/*
限时等待,在时间范围内等价于pthread_cond_wait,超过时间范围直接返回。
abstime绝对时间
 */
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
           pthread_mutex_t *restrict mutex,
           const struct timespec *restrict abstime);

唤醒

#include <pthread.h>
/*
功能:唤醒至少一个阻塞在条件变量上的线程
参数:cond已初始化的条件变量
返回值:成功返回0,失败返回错误号
*/
int pthread_cond_signal(pthread_cond_t *cond);
/*
功能:唤醒所有阻塞在条件变量上的线程 
*/
int pthread_cond_broadcast(pthread_cond_t *cond);

实例

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

pthread_mutex_t mutex;      /* 定义互斥锁变量 */
pthread_cond_t cond;        /* 定义条件变量 */
char buf[] = "0123456789";

/* 定义数组元素输出子线程执行函数 */
void * prt_arr(void *arg)
{
    while(1) {
        /* 加锁 */
        pthread_mutex_lock(&mutex);
        /* 设置等待条件 */
        pthread_cond_wait(&cond, &mutex);   
        printf("%s\n", buf);
        /* 解锁 */
        pthread_mutex_unlock(&mutex);
        //sleep(1);
    }
}

/* 定义数组元素倒序子线程执行函数 */
void *reverse_arr(void *arg)
{
    int i;
    char tmp;
    while(1) {
        /* 加锁 */
        pthread_mutex_lock(&mutex);
        for (i = 0; i < 5; i++) {
            tmp = buf[i];
            buf[i] = buf[9-i];
            buf[9-i] = tmp;
        }
        /* 唤醒阻塞在cond条件下的线程 */
        pthread_cond_signal(&cond);
        /* 解锁 */
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
}

int main()
{
    int ret;
    pthread_t prt_id;
    pthread_t reverse_id;
    /* 初始化互斥锁 */
    pthread_mutex_init(&mutex, NULL);
    /* 初始化添加变量 */
    pthread_cond_init(&cond, NULL);
    /* 生产者线程:倒序 */
    ret = pthread_create(&reverse_id, NULL, reverse_arr, NULL);
    if (ret != 0) {
        fprintf(stderr, "create video pthread fail\n");
        return -1;
    }
    /* 消费者线程:输出数组元素 */
    ret = pthread_create(&prt_id, NULL, prt_arr, NULL);
    if (ret != 0) {
        fprintf(stderr, "create video pthread fail\n");
        return -1;
    }
    while(1) {
        printf("main pthread\n");
        sleep(10);
    }
    /* 销毁添加变量 */
    pthread_cond_destroy(&cond);
    /* 销毁互斥锁 */
    pthread_mutex_destroy(&mutex);
}
上一篇下一篇

猜你喜欢

热点阅读