pthread_cond_timedwait的概念和使用案例

devtools/2025/2/6 10:19:52/

pthread_cond_timedwait 是 POSIX 线程库中用于条件变量等待的函数,允许线程在等待某个条件时设置超时时间。以下是其概念和示例:


概念

  1. 作用
    线程等待条件变量被触发,但最多等待到指定的超时时间。若超时前条件未被触发,线程自动唤醒并继续执行。

  2. 参数

    int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
    
    • cond:要等待的条件变量。
    • mutex:与条件变量关联的互斥锁,调用前需已加锁。
    • abstime:绝对超时时间(从 Epoch 开始的秒和纳秒)。
  3. 返回值

    • 0:条件变量被触发(可能是正常唤醒或虚假唤醒)。
    • ETIMEDOUT:超时后未收到信号。
    • 其他错误码:如互斥锁问题。
  4. 注意事项

    • 必须与互斥锁配合使用。
    • 超时时间是绝对时间(如 CLOCK_REALTIME),需通过系统时间计算。

使用案例

场景:生产者-消费者模型

消费者线程等待任务队列非空,但最多等待 5 秒。若超时则处理其他逻辑。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int task_available = 0; // 模拟任务是否存在void *consumer(void *arg) {struct timespec ts;while (1) {pthread_mutex_lock(&mutex);// 设置超时时间:当前时间 + 5 秒clock_gettime(CLOCK_REALTIME, &ts);ts.tv_sec += 5;// 等待条件变量或超时while (!task_available) {int ret = pthread_cond_timedwait(&cond, &mutex, &ts);if (ret == ETIMEDOUT) {printf("等待超时,处理其他逻辑...\n");pthread_mutex_unlock(&mutex);// 此处可添加超时处理代码return NULL;} else if (ret != 0) {perror("pthread_cond_timedwait");exit(1);}}// 执行任务处理printf("处理任务...\n");task_available = 0; // 重置任务状态pthread_mutex_unlock(&mutex);}return NULL;
}// 生产者线程(示例中未完整实现)
void *producer(void *arg) {// 生产任务并触发条件变量pthread_mutex_lock(&mutex);task_available = 1;pthread_cond_signal(&cond);pthread_mutex_unlock(&mutex);return NULL;
}int main() {pthread_t tid_consumer, tid_producer;pthread_create(&tid_consumer, NULL, consumer, NULL);// pthread_create(&tid_producer, NULL, producer, NULL);pthread_join(tid_consumer, NULL);// pthread_join(tid_producer, NULL);pthread_cond_destroy(&cond);pthread_mutex_destroy(&mutex);return 0;
}

关键点解释

  1. 超时时间计算
    使用 clock_gettime(CLOCK_REALTIME, &ts) 获取当前时间,再增加 5 秒作为绝对超时时间。

  2. 循环检查条件
    即使被唤醒(可能因虚假唤醒),仍需检查条件是否满足(while (!task_available))。

  3. 返回值处理

    • 若返回 ETIMEDOUT,线程主动处理超时逻辑。
    • 其他错误需终止或处理异常。

注意事项

  • 互斥锁必要性:调用 pthread_cond_timedwait 前必须持有互斥锁,函数内部会释放锁并在返回前重新获取。
  • 时间精度timespec 使用纳秒级精度,但实际精度依赖系统实现。
  • 虚假唤醒:即使未超时或未被唤醒,线程也可能被唤醒,因此条件检查必须放在循环中。

通过合理使用 pthread_cond_timedwait,可以实现带超时的线程同步,避免永久阻塞。


http://www.ppmy.cn/devtools/156518.html

相关文章

android java 用系统弹窗的方式实现模拟点击动画特效

接上一篇&#xff1a;android java系统弹窗的基础模板-CSDN博客 本篇记录的是系统弹窗的一个应用示例&#xff1a;实现点击动画效果 首先模拟点击的实现参考&#xff1a;android模拟点击_motionevent upevent motionevent.obtain(systemclo-CSDN博客 动画效果&#xff0c;是…

YONBIP后端环境搭建-IDEA

1、IDEA环境搭建 1.1、插件安装 打开设置窗口&#xff0c;添加自定义插件存储库路径。 https://nccdev.yonyou.com/ide/idea/latest/updatePlugin.xml 在 Marketplace 中搜索 YonBuilder Premium开发者工具 &#xff0c;点击安装。 1.2、Home配置 点击Home配置按钮&#xf…

PopupMenuButton组件的功能和用法

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了Sliver综合示例相关的内容&#xff0c;本章回中将介绍PopupMenuButton组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的PopupMenuButton组件位于AppBar右侧&#xff0c;…

《大语言模型》综述学习笔记

《A Survey of Large Language Models》英文版综述最近出了中文版书——《大语言模型》&#xff0c;本博客作为阅读笔记记录一下&#xff0c;综述主页&#xff1a;https://github.com/RUCAIBox/LLMSurvey 关于LLM的一些概述和理解 记录一些有启发性的说法&#xff1a; 1、当前…

2025年1月22日(网络编程 udp)

系统信息&#xff1a; ubuntu 16.04LTS Raspberry Pi Zero 2W 系统版本&#xff1a; 2024-10-22-raspios-bullseye-armhf Python 版本&#xff1a;Python 3.9.2 已安装 pip3 支持拍摄 1080p 30 (1092*1080), 720p 60 (1280*720), 60/90 (640*480) 已安装 vim 已安装 git 学习…

Spark--算子执行原理

一、sortByKey SortByKey是一个transformation算子&#xff0c;但是会触发action&#xff0c;因为在sortByKey方法内部&#xff0c;会对每个分区进行采样&#xff0c;构建分区规则&#xff08;RangePartitioner&#xff09;。 内部执行流程 1、创建RangePartitioner part&…

FBX SDK的使用:基础知识

Windows环境配置 FBX SDK安装后&#xff0c;目录下有三个文件夹&#xff1a; include 头文件lib 编译的二进制库&#xff0c;根据你项目的配置去包含相应的库samples 官方使用案列 动态链接 libfbxsdk.dll, libfbxsdk.lib是动态库&#xff0c;需要在配置属性->C/C->预…

[CMake]报错: Qt requires a C++17 compiler

1.报错&#xff1a; #error 指令: "Qt requires a C17 compiler, and a suitable value for __cplusplus. On MSVC, you must pass the /Zc:__cplusplus option to the compiler." 2.解决 Qt5项目升级到Qt6项目&#xff0c;cmake需要做兼并配置&#xff1b; # 设置…