liunx:pthread_cond_t条件变量pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast

2023-11-03

liunx:pthread_cond_t条件变量pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast


一、pthread_cond_t条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

     状态变量是一种同步设备,它允许线程挂起并放弃CPU时间以等待某些共享变量满足状态。操作状态变量的基本操作:当状态满足时发送信号,等待状态满足,在其它线程发送状态信号之前挂起线程。
  状态变量通常和互斥体联系在一起,为了避免竞争状态出现,一个线程准备等待一个状态变量之前另外一个线程要先设置好状态信号。

二、pthread_cond_init函数 

      pthread_cond_init初始化状态变量cond,使用cond_attr中定义了的状态属性,如果cond_attr为NULL,将会使用默认属性。LinuxThreads的实现支持没有任何属性的cond_attr,因此,cond_attr就是被忽略的。

int pthread_cond_init(   
                  pthread_cond_t *cond,   
                  const pthread_cond_attr_t*attr   
                  );   
//该函数按参数attr指定的属性创建一个条件变量。调用成功返回,   
//并将条件变量ID 赋值给参数cond,否则返回错误代码

三、pthread_cond_wait

      pthread_cond_wait总和一个互斥锁结合使用。在调用pthread_cond_wait前要先获取锁。pthread_cond_wait函数执行时先自动释放指定的锁,然后等待条件变量的变化。在函数调用返回之前,自动将指定的互斥量重新锁住。

int pthread_cond_wait (   
                   pthread_cond_t *cond ,   
                   pthread_mutex_t*mutex   
                   );   
// 该函数调用为参数mutex 指定的互斥体解锁,等待一个事件(由   
//参数cond 指定的条件变量)发生。调用该函数的线程被阻塞直到有其他   
//线程调用pthread_cond_signal 或pthread_cond_broadcast 函数置相应的条   
//件变量,而且获得mutex 互斥体时才解除阻塞

四、pthread_cond_signal函数

int pthread_cond_signal(   
                    pthread_cond_t *cond   
                    );   
// 该函数的作用是解除一个等待参数cond所指定的条件变量的线程的阻塞状态。当有多个线程挂起等待该条件变量,也只唤醒一个线程。  

     pthread_cond_signal函数重新开始一个正在等待cond变量的线程。如果没有线程在等待cond变量,不执行任何操作。如果有多个线程都在等待,某个匹配的线程会被重新开始,但是不一定是哪个。

五、pthread_cond_broadcast函数

nt pthread_cond_broadcast(   
                       pthread_cond_t *cond   
                       );   
// 该函数用来对所有等待参数cond所指定的条件变量的线程解除阻塞,调用成功返回0,否则返回错误代码。   

     pthread_cond_broadcast函数重新开始所有在等待cond变量的线程。如果没有线程在等待cond变量,不执行任何操作。

六、pthread_cond_destroy函数

int pthread_cond_destroy(   
                     pthread_cond_t *cond   
                     );   
// 该函数的作用是释放一个条件变量。释放为条件变量cond 所分配的资源。调用成功返回值为0,否则返回错误代码。 

     pthread_cond_destroy函数销毁状态变量,释放它可能持有的资源。没有线程必须在这里等待状态变量。在LinuxThreads实现中,状态变量不与任何资源有关系,所以这个接口除了检查状态变量上是否有等待的线程之外不做任何事。


七、等待和激发

       等待条件有两种方式:条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEDOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间1970年1月1日0时0分0秒。

   无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race Condition)。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。阻塞时处于解锁状态。
       激发条件有两种形式,pthread_cond_signal()激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;而pthread_cond_broadcast()则激活所有等待线程。


八、典型的实例学习,看注释即可。

1、pthread_cond_signal.c

#include<pthread.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
 
static pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
 
struct node {
    int n_number;
    struct node *n_next;
} *head=NULL; /*[thread_func]*/
 
/*释放节点内存*/
static void cleanup_handler(void*arg) {
    printf("Clean up handler of second thread.\n");
    free(arg);
    (void)pthread_mutex_unlock(&mtx);
}
 
static void *thread_func(void *arg) {
    struct node*p=NULL;
    pthread_cleanup_push(cleanup_handler,p);
 
    pthread_mutex_lock(&mtx);
    //这个mutex_lock主要是用来保护wait等待临界时期的情况,
    //当在wait为放入队列时,这时,已经存在Head条件等待激活
    //的条件,此时可能会漏掉这种处理
    //这个while要特别说明一下,单个pthread_cond_wait功能很完善,
    //为何这里要有一个while(head==NULL)呢?因为pthread_cond_wait
    //里的线程可能会被意外唤醒,如果这个时候head==NULL,
    //则不是我们想要的情况。这个时候,
    //应该让线程继续进入pthread_cond_wait
	//printf("thread_func sleeping....\n");
	//sleep(2);
	//printf("thread_func end sleep....\n");
    while(1) 
	{
        while(head==NULL) 
		{
			printf("head=NULL   pthread_cond_wait....\n");
            pthread_cond_wait(&cond,&mtx);
			printf("head is not null now ,go ahead! \n   pthread_cond_wait end\n");
        }
        //pthread_cond_wait会先解除之前的pthread_mutex_lock锁定的mtx,
        //然后阻塞在等待队列里休眠,直到再次被唤醒
        //(大多数情况下是等待的条件成立而被唤醒,唤醒后,
        //该进程会先锁定先pthread_mutex_lock(&mtx);,
        //再读取资源用这个流程是比较清楚的
        /*block-->unlock-->wait()return-->lock*/
        p=head;
        head=head->n_next;
        printf("Got%dfromfrontofqueue\n",p->n_number);
        free(p);
    }
    pthread_mutex_unlock(&mtx);//临界区数据操作完毕,释放互斥锁
 
    pthread_cleanup_pop(0);
    return 0;
}
 
int main(void) {
    pthread_t tid;
    int i;
    struct node *p;
    pthread_create(&tid,NULL,thread_func,NULL);
    //子线程会一直等待资源,类似生产者和消费者,
    //但是这里的消费者可以是多个消费者,
    //而不仅仅支持普通的单个消费者,这个模型虽然简单,
    //但是很强大
    for(i=0;i<5;i++) 
	{
        p=(struct node*)malloc(sizeof(struct node));
        p->n_number=i;
        pthread_mutex_lock(&mtx);//需要操作head这个临界资源,先加锁,
        p->n_next=head;
        head=p;
		printf("pthread_cond_signal  i=%d\n",i);
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mtx);//解锁
		printf("sleeping....\n");
        sleep(1);
		printf("sleep end ....\n");
		
    }
    printf("thread1wannaendthecancelthread2.\n");
    pthread_cancel(tid);
    //关于pthread_cancel,有一点额外的说明,它是从外部终止子线程,
    //子线程会在最近的取消点,退出线程,而在我们的代码里,最近的
    //取消点肯定就是pthread_cond_wait()了。
    pthread_join(tid,NULL);
    printf("Alldone--exiting\n");
    return 0;
}
     2、编译&执行


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

liunx:pthread_cond_t条件变量pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast 的相关文章

  • 06makefile学习之三个自动变量($@,$^,$<),模式规则和静态模式规则

    06makefile学习之三个自动变量 lt 和模式规则 以下为相关makefile的学习文章 01makefile学习之GCC编译的四个阶段 带编译阶段 汇编阶段 S c的区别 02makefile学习之makefile的基本原则 03m
  • vim编辑器使用教程

    文章目录 前言 一 vim 的三种工作模式 二 vim 基本操作 1 编辑 2 复制粘贴 3 撤销 4 跳转 5 查找和替换 6 自动缩进 7 分屏 8 其他 三 vim 配置文件 前言 vim 是 Linux 系统内置的 文本编辑器 用于
  • 01LinuxC线程学习之线程概念,简述与进程区别和查看LWP轻量级线程号(不是PID也不是TID))

    1 线程 1 1 线程概念 1 线程概念 每个线程有各自的PCB 但没有独立的地址空间 共享 注 该地址空间指的是以进程为单位 不是指栈 而进程拥有独立地址空间 拥有PCB 2 LWP light weight process 轻量级的进程
  • xxxx is deprecated

    编译工程发现json object object get is deprecated 最终解决 jason c库中有声明 deprecated Please use json object object get ex json c库编译的时
  • 进程间同步(互斥量、信号量)

    进程间同步可以使用互斥量mutex 互斥锁 信号量和文件锁 进程间同步使用信号量 int sem init sem t sem int pshared unsigned int value 用于进程间同步此时第二个参数不能取0了 取非0值用
  • 线程的属性 —— 分离的状态(detached state)、栈地址(stack address)、栈大小(stack size)

    参考 四十二 线程 线程属性 作者 FadeFarAway 发布时间 2017 01 17 14 09 55 网址 https blog csdn net FadeFarAway article details 54576771 目录 引入
  • Posix信号量

    Posix信号量 一 Posix信号量 1 概述 二 Posix提供两种信号量 有名信号量和基于内存的信号量 三 命名信号量 1 sem open和sem close函数 2 sem unlink函数 3 sem wait函数 5 sem
  • Linux系统编程——文件编程(四)光标移动(lseek)

    lseek函数 lseek是一个用于改变读写一个文件时读写指针位置的一个系统函数 每个打开的文件都有一个与其相关联的 当前文件偏移量 它通常是一个非负整数 用以度量从文件开始处计算的字节数 通常 读 写操作都从当前文件偏移量处开始 并使偏移
  • Makefile(面试必备)

    1 Makefile基本介绍 1 1 makefile介绍 make是一个工程管理器 它可以根据文件时间自发检测更新的文件从而减少编译量 makefile文件和make工具一起使用 用于控制工程项目的编译和链接 也可以用来编写手册页和程序的
  • 10LinuxC线程学习之pthread_detach函数,错误返回值分析及其案例

    1 pthread detach函数 int pthread detach pthread t thread 功能 1 实现线程分离 不再受主线程管理 由系统接任 线程结束后 其退出状态不由其他线程获取 而直接自己自动释放 网络 多线程服务
  • 14LinuxC线程学习之查看当前pthread库版本和线程使用的注意事项(重要)

    1 查看当前pthread库版本 1 查看当前pthread库版本 getconf GNU LIBPTHREAD VERSION 2 NPTL名词了解 NPTL实现机制 POSIX Native POSIX Thread Library 3
  • Linux进程的讲解(僵尸进程、孤儿进程)

    进程 程序就是你编译过后产生的那个文件 进程就是打开程序过后产生的 fork vfork exit execl system popen 孤儿进程 僵尸进程 wait fork1 getpid getppid区别 pid t getpid
  • Linux工具——gcc

    目录 一 gcc简介 二 C语言源文件的编译过程 1 预处理 2 编译 3 汇编 4 链接 5 动静态库 一 gcc简介 相信有不少的小白和我一样在学习Linux之前只听说过visual studio 其实这个gcc这个编译器实现的功能便是
  • Linux系统编程(七)--线程控制

    文章目录 1 线程属性 1 1 pthread attr t 1 2 不同属性的作用 2 互斥量的共享属性 2 1 属性的初始化与回收 2 2 共享属性 3 互斥量的鲁棒属性 3 1 相关函数 3 2 互斥量状态一致性 4 递归型互斥量 4
  • 【Linux系统编程(二)】Linux文件IO操作

    文章目录 Linux文件IO操作 1 系统调用 2 系统调用和库函数的区别 3 C库中IO函数工作流程 4 文件描述符 4 1 文件描述符表是如何管理文件描述符的呢 4 2 查看当前系统文件描述最大数量 5 文件IO的操作 5 1 open
  • linux系统函数总结(一)

    realpath include
  • exec族函数配合fork使用(linux系统编程)

    execl 函数配合fork 函数 在执行A程序的过程中去执行B程序 代码B 用来改文件中的数值 include
  • 八、Linux编程之递归遍历目录

    八 Linux编程之递归遍历目录 目录 八 Linux编程之递归遍历目录 一 步骤分析 二 isFile 函数 三 isDir 函数 int sprintf char str const char format 四 main 主函数 五 运
  • 【hello Linux】进程间通信——共享内存

    目录 前言 1 System V共享内存 1 共享内存的理解 2 共享内存的使用步骤 3 共享内存的使用 1 共享内存的创建 查看共享内存 2 共享内存的释放 3 共享内存的挂接 4 共享内存的去挂接 4 共享内存的使用示例 1 两进程挂接
  • Linux·进程权限控制

    Linux系统的安全性得益于其进程权限和文件权限的控制机制 今天抽空梳理下Linux下的进程权限控制相关的文件权限涉及一点 首先明确四个名词 真实用户ID real ID 有效用户ID effective ID 保存用户ID Saved I

随机推荐

  • 【华为OD机试真题 Java】上班之路 (A卷2022Q4)

    前言 本专栏将持续更新华为OD机试题目 并进行详细的分析与解答 包含完整的代码实现 希望可以帮助到正在努力的你 关于OD机试流程 面经 面试指导等 如有任何疑问 欢迎联系我 wechat steven moda email nansun09
  • MySQL架构原理(MySQL体系架构、MySQL运行机制、MySQL存储引擎)

    一 MySQL体系架构 MySQL Server架构大致可以分为 网络连接层 服务层 存储引擎层和系统文件层 网络连接层 客户端连接器 Client Connectors 提供与MySQL服务器建立连接的支持 目前主流服务器编程技术 例如
  • SpringBoot发送http请求

    SpringBoot发送http请求 添加依赖
  • 隐变量(Hidden Variables)

    在软件开发的过程中的确存在另外的变量 但是他们并不是隐变量的 我们只是忽略了它们 这些被称为 人 的变量很多人都有可能成为 它具有不可预知性除非你在寻找一种方法论来排除他们 应用方法论的目的是什么呢 我认为就是得到一个可以忽略掉任何相关的独
  • 【AI文本工具站】日活近4万

    前言 承蒙网友厚爱 AI文本工具站 目前日活已经近4万 每天对话超过30万次 作为一个免费的工具网站 能够得到这么多人的认可和使用 真的是莫大的荣幸 点击前往 AI文本工具站 功能介绍 ChatGPT对话 国内可用 免费 免登录 无限制 文
  • Acwing3508 最长公共子串

    Acwing3508 最长公共子串 一眼dp 定义f i j 为以a i 结尾的a的子串与以b j 结尾的b的子串的最大公共后缀串的长度 分析最后一步 用a i 1 lt i lt strlen a 与 b j 1 lt j lt strl
  • P3612 [USACO17JAN]Secret Cow Code S 分治 (清楚思路 + 代码简洁)

    题目链接 P3612 USACO17JAN Secret Cow Code S 这道题的思路是给你一个字符串 这个字符串变长的规律是先加尾结点 然后再把前面的部分平移到后面 a b 反 转 后
  • 云笔记横向评测:印象笔记、有道云笔记、为知笔记、OneNote、Notion

    某款软件是否好用 既需要根据其功能特性评估其优点和缺点 也需要分析用户的基本需求 以下是常见云笔记的深度评测 云笔记评测标准 分析每款笔记软件的核心特色 优点 缺点及使用场景 具体包括 印象笔记 有道云笔记 为知笔记 OneNote Not
  • 安卓第三方开源库

    原文在简书 这是地址 Android开源库V Layout 淘宝 天猫都在用的UI框架 赶紧用起来吧 安卓开发者不得不收藏的工具学技术就去懒人博客安卓那些你不得不收藏的开源库GitHub上受欢迎的Android UI Library And
  • 【华为OD统一考试B卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • Linux查看进程cpu占用情况

    项目上线后运行一段时间 突然发现cpu 8个逻辑核心都占用100 心情很紧张 然后就在网上找了一些解决方法 具体如下 1 查找哪些进程在耗cpu 进入服务器 top 命令看一下 发现进程6633占用了800 root 3server top
  • g++编译c和c++混合代码的Makefile写法

    在之前的一文章里介绍了多目录Makefile的写法 但是仅针对纯c或者c 代码 而有些时候我们需要混合编译c和c 代码 我们只需要使用g 来编译代码即可 只要我们做两点改动 第一 在引用需要c编译的头文件时 使用关键字extern C 括起
  • KDE桌面没有wifi的解决方案

    ubuntu重装的KDE桌面 但是没有wifi图标 解决方案是 sudo apt get install plasma nm reboot
  • burp intruder爆破出现 Payload set 1: Invalid number settings的解决办法

    如果点击start attrack 后出现 Payload set 1 Invalid number settings 的提示 先点hex 后点 decimal 再开始start attrack 这是一个软件bug 需要手动让它刷新 如果你
  • onenote冲突服务器显示,ONENOTE同步分区失败,显示“正在等待另一个设备完成上载您的笔记”?...

    ONENOTE同步分区失败 显示 正在等待另一个设备完成上载您的笔记 一直在用OneNote 不过之前都没在意分区问题 就是一直添加页面放很多东西进去 问题从昨晚开始出现的 打开OneNote 一如既往用win10自带截图工具截图后复制 在
  • Faster—RCNN配置matlab使用教程

    1 电脑配置 本人电脑的配置 Windows10 64位 MATLAB 2013b CUDA6 5 VS 2013 这里给大家说个小BUG MATLAB2013a是不支持gpuarray的 如果你是2013a的话 会一直报这句错误的 所以
  • 剑指 Offer 57 - II. 和为s的连续正数序列 -—思路和心得

    你在一起 这是一道典型的滑动窗口题目 解题思路就是对于小于target的每一个数都创建一个滑动窗口 通过窗口滑动来进行判断 我的题解 class Solution 思路 滑动窗口解题 1 用变量j代表滑动窗口的结束 2 用变量i从0到tar
  • 位域 (bit-field)

    位域 bit field 也叫位段 所谓 位域 实际上就是把一个字节中的二进位划分为几个不同的区域 并说明每个区域的位数 每个域有一个域名 允许在程序中按域名进行操作 这样就可以把几个不同的对象用一个字节的二进制位域来表示 其主要优点当然就
  • GDI+ 中的一些基础类

    GDI 学习系列 Qt中使用GDI 绘图 背景 GDI 是 Windows 提供的图形设备接口 GDI 的后续版本 相比 GDI GDI 是面向对象的 使用更方便 在 Qt 中也可以使用 GDI 进行绘图 Point GDI 中使用 Poi
  • liunx:pthread_cond_t条件变量pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast

    liunx pthread cond t条件变量pthread cond wait pthread cond signal pthread cond broadcast 一 pthread cond t条件变量是利用线程间共享的全局变量进行