当前位置: 移动技术网 > 网络运营>服务器>Linux > 【linux系统编程学习笔记】第十三节:线程的安全机制3(条件变量)(pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast)

【linux系统编程学习笔记】第十三节:线程的安全机制3(条件变量)(pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast)

2020年07月29日  | 移动技术网网络运营  | 我要评论

线程的安全机制3——条件变量

条件变量

条件变量API

pthread_cond_init   初始化一个条件变量

pthread_cond_destroy  销毁一个条件变量

pthread_cond_wait   条件变量等待函数

pthread_cond_timedwait  规定等待时间的条件变量等待函数

pthread_cond_signal  唤醒一个因为条件变量而陷入睡眠的线程

pthread_cond_broadcast  广播唤醒所有因为条件变量而陷入睡眠的线程

例程:


条件变量

概念:

        专门为了互斥锁而诞生的辅助工具,条件变量是一种同步机制,允许线程挂起,直到共享数据上的某些条件得到满足。条件变量上的基本操作有:触发条件(当条件变为 true 时);等待条件,挂起线程直到其他线程触发条件。

条件变量API

pthread_cond_init   初始化一个条件变量

pthread_cond_destroy  销毁一个条件变量

#include <pthread.h>  
int pthread_cond_init(pthread_cond_t *restrict cond,            
            const pthread_condattr_t *restrict attr); 
int pthread_cond_destroy(pthread_ cond _t * cond);

函数功能

  • pthread_cond_init:条件变量的初始化
  • pthread_cond_destroy:销毁一个条件变量

参数

  • cond:需要的条件变量
  • Attr:这个参数设置为NULL,代表按照默认的条件进行初始化

返回值:

  • 成功则返回0,失败则返回一个错误值,errno没有被设置

pthread_cond_wait   条件变量等待函数

pthread_cond_timedwait  规定等待时间的条件变量等待函数

#include <pthread.h>   
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_wait:条件变量等待函数,一旦调用这个函数,线程便会经历以下步骤,一直等待被唤醒:

                                   解开互斥锁->线程睡眠->等待被唤醒…

                                   被唤醒后->线程启动->给互斥锁加锁

  • pthread_cond_timedwait:规定等待时间的条件变量等待函数,跟上面的函数功能跟逻辑是一样的,只是多加了一个时间参数,超过这个时间便不会等待,直接返回错误。

参数:

  • cond:要操作的条件变量
  • mutex:要操作的互斥锁
  •  abs_timeout:等待的时间限制

struct timespec {     
    time_t tv_sec;      /* 秒级单位*/     
    long   tv_nsec;     /* 微秒级别单位 */ 
};

返回值:

  • 成功则返回0,失败则返回一个错误值,errno没有被设置

pthread_cond_signal  唤醒一个因为条件变量而陷入睡眠的线程

pthread_cond_broadcast  广播唤醒所有因为条件变量而陷入睡眠的线程

#include <pthread.h>  
int pthread_cond_signal(pthread_cond_t *cond); 
int pthread_cond_broadcast(pthread_cond_t *cond);

函数功能

  • pthread_cond_signal:唤醒一个最早因为条件变量而陷入睡眠的线程
  • pthread_cond_broadcast:唤醒全部因为条件变量而陷入睡眠的线程

参数:

  • cond:要操作的条件变量

返回值:

  • 成功则返回0,失败则返回一个错误值,errno没有被设置

例程:

#include "common.h"
//
int count = 10;

//定义互斥锁
pthread_mutex_t mutex;
//定意思条件变量
pthread_cond_t cond;


//子线程函数
void *change_count(void *arg)
{
    while(1)
    {
        //上锁
        pthread_mutex_lock(&mutex);
        while(count<=0)
        {
            //count<=0解锁并进入睡眠
            pthread_cond_wait(&cond,&mutex);
            continue;
        }
        count-=1;
        printf("我是thread %s 现在count = %d\n",(char *)arg,count);
        //解锁
        pthread_mutex_unlock(&mutex);
        sleep(1);

    }
}

void sighnad(int signum)
{
    count +=10;
    printf("thrads count = %d\n",count);
    //唤醒一个线程
    pthread_cond_signal(&cond);
    //广播唤醒所有线程
//    pthread_cond_broadcast(&cond);
}

int main()
{
    //捕捉SIGINT信号
    signal(SIGINT,sighnad);
    //初始化互斥锁
    pthread_mutex_init(&mutex,NULL);
    //初始化条件变量
    pthread_cond_init(&cond,NULL);

    //子线程ID
    pthread_t tid1,tid2,tid3;
    char cmd[32];

    //创建3个子线程
    pthread_create(&tid1,NULL,change_count,(void *)"1");
    pthread_create(&tid2,NULL,change_count,(void *)"2");
    pthread_create(&tid3,NULL,change_count,(void *)"3");

    while(1)
    {
        bzero(cmd,sizeof(cmd));
        fgets(cmd,sizeof(cmd),stdin);
//        scanf("%s",cmd);
        //用户输入"exit"杀死三个子线程
        if(strncmp(cmd,"exit",strlen(cmd)-1)==0)
        {
            pthread_cancel(tid1);
            pthread_cancel(tid2);
            pthread_cancel(tid3);
            printf("杀死了3个子线程\n");
            break;
        }
    }
//    pthread_join(tid1,NULL);
//    pthread_join(tid2,NULL);
//    pthread_join(tid3,NULL);

    //删除互斥锁与条件变量
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);
    printf("main exit\n");
    return 0;
}

 

本文地址:https://blog.csdn.net/qq_44796935/article/details/107619083

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网