Linux系统编程-(pthread)线程通信(条件变量)

简介: 条件变量是线程可用的一种同步机制,条件变量给多个线程提供了一个回合的场所,条件变量和互斥量一起使用,允许线程以无竞争的方式等待特定的条件发生。条件变量本身是由互斥体保护的,线程在改变条件状态之前必须首先锁住互斥量,其他线程在获取互斥量之前就不会觉察到这种变化,因为互斥量必须锁定之后才改变条件。

1. 条件变量介绍

条件变量是线程可用的一种同步机制,条件变量给多个线程提供了一个回合的场所,条件变量和互斥量一起使用,允许线程以无竞争的方式等待特定的条件发生。

条件变量本身是由互斥体保护的,线程在改变条件状态之前必须首先锁住互斥量,其他线程在获取互斥量之前就不会觉察到这种变化,因为互斥量必须锁定之后才改变条件。

条件变量总结:

  1. 条件变量要配合互斥锁使用。
  2. 条件变量支持单个唤醒和广播方式唤醒。

下面是视频监控的一个项目模型,摄像头的数据使用条件变量保护:

image-20211219155142591

2. 条件变量相关接口函数

2.1 条件变量初始化与销毁

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
用法示例示例:
pthread_cond_t cond;
pthread_cond_init(&cond, NULL);

int pthread_cond_destroy(pthread_cond_t *cond);
成功返回0,否则返回错误码

pthread_cond_init 用于初始化条件变量,最后使用完毕需要调用pthread_cond_destroy销毁。

2.2 条件变量等待与唤醒

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

pthread_cond_broadcast 函数用于广播唤醒所有等待条件的休眠线程。

pthread_cond_signal函数按顺序唤醒一个休眠的线程。

pthread_cond_wait 函数阻塞方式等待条件成立。第二个参数填互斥锁指针。

总结:

pthread_cond_signal函数一次性可以唤醒阻塞队列中的一个线程,pthread_cond_broadcast函数一次性可以唤醒阻塞队列中的所有线程。

3. 案例代码: 条件变量使用案例

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>

pthread_cond_t cond;
pthread_mutex_t mutex;
/*
线程工作函数--消费者
*/
void *thread_work_func(void *dev)
{
    int i=(int)dev;
    printf("第%d个线程等待运行...\n",i);

    //互斥锁上锁
    pthread_mutex_lock(&mutex);
    printf("互斥锁上锁成功.%d \n",i);
    pthread_cond_wait(&cond,&mutex); //内部先解锁再加锁
    pthread_mutex_unlock(&mutex);
    printf("第%d个线程开始运行...\n",i);
}

//信号工作函数---生产者
void signal_work_func(int sig)
{
    printf("正在唤醒休眠的线程.\n");
    pthread_mutex_lock(&mutex);
    pthread_cond_broadcast(&cond); //广播唤醒
    //pthread_cond_signal (&cond); //唤醒单个休眠的线程
    pthread_mutex_unlock(&mutex);
}

int main(int argc,char **argv)
{   
    //注册要捕获的信号
    signal(SIGINT,signal_work_func);

    //初始化条件变量
    pthread_cond_init(&cond,NULL);
    //初始化互斥锁
    pthread_mutex_init(&mutex,NULL);
    
    /*创建子线程*/
    pthread_t thread_id;
    int i;
    for(i=0;i<10;i++)
    {
        if(pthread_create(&thread_id,NULL,thread_work_func,(void*)i)!=0)
        {
            printf("子线程%d创建失败.\n",i);
            return -1;
        }
        //设置线程的分离属性
        pthread_detach(thread_id);
        sleep(1);
    }

    while(1)
    {

    }

    //销毁条件变量
    pthread_cond_destroy(&cond);
    //销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return 0;
}
目录
相关文章
|
16天前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
145 78
|
15天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
78 13
|
16天前
|
Ubuntu Linux C++
Win10系统上直接使用linux子系统教程(仅需五步!超简单,快速上手)
本文介绍了如何在Windows 10上安装并使用Linux子系统。首先,通过应用商店安装Windows Terminal和Linux系统(如Ubuntu)。接着,在控制面板中启用“适用于Linux的Windows子系统”并重启电脑。最后,在Windows Terminal中选择安装的Linux系统即可开始使用。文中还提供了注意事项和进一步配置的链接。
39 0
|
3月前
|
安全 Linux
Linux线程(十一)线程互斥锁-条件变量详解
Linux线程(十一)线程互斥锁-条件变量详解
|
7月前
|
API
linux---线程互斥锁总结及代码实现
linux---线程互斥锁总结及代码实现
|
6月前
|
安全 算法 Linux
【Linux】线程安全——补充|互斥、锁|同步、条件变量(下)
【Linux】线程安全——补充|互斥、锁|同步、条件变量(下)
57 0
|
6月前
|
存储 安全 Linux
【Linux】线程安全——补充|互斥、锁|同步、条件变量(上)
【Linux】线程安全——补充|互斥、锁|同步、条件变量(上)
62 0
|
8月前
|
安全 Linux 调度
【linux线程(二)】线程互斥与线程同步
【linux线程(二)】线程互斥与线程同步
|
8月前
|
安全 算法 Linux
【Linux 系统】多线程(线程控制、线程互斥与同步、互斥量与条件变量)-- 详解(下)
【Linux 系统】多线程(线程控制、线程互斥与同步、互斥量与条件变量)-- 详解(下)
|
8月前
|
存储 Linux 程序员
【Linux 系统】多线程(线程控制、线程互斥与同步、互斥量与条件变量)-- 详解(中)
【Linux 系统】多线程(线程控制、线程互斥与同步、互斥量与条件变量)-- 详解(中)