【PTHREAD】线程互斥与同步之条件变量

互斥量能够保证在微观层面同一时刻仅有一个线程处理变量,但是不能保证执行顺序,更不能在某一时刻,一个线程通知另一个线程开始开始处理相关任务。

1 条件变量属性类型

#define __SIZEOF_PTHREAD_MUTEXATTR_T 4

typedef union
{
  char __size[__SIZEOF_PTHREAD_CONDATTR_T];
  int __align;
} pthread_condattr_t;

2 初始化与销毁条件变量属性

int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
  • pthread_condattr_init
    • 以默认值初始化条件变量属性。
    • 完成初始化以后,可使用该条件变量属性创建一个或多个条件变量。
    • 修改或销毁条件变量不影响使用该属性创建的条件变量。
    • 初始化一个已初始化的条件变量属性对象,将导致不确定性行为
  • pthread_condattr_destroy
    • 销毁指定条件变量属性对象
    • 执行完成后,条件变量属性对象编程未初始化状态
    • 已销毁的条件变量属性对象可以被再次初始化
    • 销毁一个已销毁的条件变量属性对象,将导致不确定性行为

3 初始化与销毁条件变量

int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init(pthread_cond_t *restrict cond,
                      const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

初始化与销毁条件变量。

  • pthread_cond_init
    • 初始化一个条件变量
    • 如果条件变量属性设置为NULL,则以默认的条件变量属性进行初始化
    • 执行成功之后,条件变量变为已初始化状态
  • pthread_cond_destroy
    • 销毁指定的条件变量
    • 执行成功后,条件变量编程未初始化状态
    • 已销毁的条件变量可以被重新初始化
    • 销毁一个已销毁的条件变量,将导致不确定性行为
    • 销毁一个已初始化且未阻塞任何线程的条件变量是可行的
    • 企图销毁一个正在使用的条件变量将导致不确定性行为

4 条件变量之阻塞

int pthread_cond_timedwait(pthread_cond_t *restrict cond,
                           pthread_mutex_t *restrict mutex,
                           const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
                      pthread_mutex_t *restrict mutex);
  • 调用这两个函数将导致线程处于阻塞到一个条件变量
  • 当收到解锁信号后,阻塞将自动解除
  • pthread_cond_timedwait该函数使线程处于阻塞状态到指定的时间,如果在指定的时间内,还未等到信号,则退出等待

5 条件变量之通知

int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
  • pthread_cond_signal

    解除多个堵塞在同一个条件变量上的线程中的其中一个

  • pthread_cond_broadcast

    解除所有阻塞在通过条件变量上的所有线程

6 案例:条件变量的使用

  • 源码

    线程一启动后进入阻塞状态,等待信号的到来。线程二在启动后,等待5秒后发出信号。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    
    void *start_routine_01(void *ptr)
    {
        printf("进入阻塞状态...\n");
        pthread_mutex_lock(&mutex);
        pthread_cond_wait(&cond, &mutex);
        printf("获得信号以解除阻塞状态...\n");
    
        pthread_mutex_unlock(&mutex);
        return (void *)NULL;
    }
    
    void *start_routine_02(void *ptr)
    {
        printf("等待5秒后发出解除信号...\n");
        sleep(5);
        pthread_mutex_lock(&mutex);
        pthread_cond_signal(&cond);
        printf("解除信号已发出...\n");
    
        pthread_mutex_unlock(&mutex);
        return (void *)NULL;
    }
    
    int main(int argc, char const *argv[])
    {
        {
            pthread_mutexattr_t attr;      // 定义互斥属性
            pthread_mutexattr_init(&attr); // 初始化互斥属性
    
            pthread_mutex_init(&mutex, &attr); // 初始化互斥
            pthread_mutexattr_destroy(&attr);  // 销毁互斥属性
        }
    
        {
            pthread_condattr_t attr;      // 定义条件变量属性
            pthread_condattr_init(&attr); // 初始化条件变量属性
    
            pthread_cond_init(&cond, &attr); // 初始化条件变量
            pthread_condattr_destroy(&attr); // 销毁条件变量属性
        }
    
        pthread_t thread_id_01;
        pthread_t thread_id_02;
    
        pthread_create(&thread_id_01, NULL, start_routine_01, NULL);
        pthread_create(&thread_id_01, NULL, start_routine_02, NULL);
    
        pthread_join(thread_id_01, NULL);
        pthread_join(thread_id_02, NULL);
    
        pthread_mutex_destroy(&mutex); // 销毁互斥
        pthread_cond_destroy(&cond);   // 销毁条件变量
    
        exit(EXIT_SUCCESS);
    }
    
  • 输出

    进入阻塞状态…
    等待5秒后发出解除信号…
    解除信号已发出…
    获得信号以解除阻塞状态…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值