pthread_cond_timedwait函数使用

article/2025/9/19 8:45:31

1 函数原型

#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);

2 注意事项

pthread_cond_timedwait()用于等待一个条件变量,等待条件变量的同时可以设置等待超时。这是一个非常有用的功能,如果不想一直等待某一条件变量,就可以使用这个函数。

2.1 abstime参数

这里面的超时时间是一个绝对值,也就是距离1970-1-1 日的时间值,而不是一个时间段。比如说当前时间为2021-5-15 17:14:00.100,我们想通过这个函数设置最大超时为2500ms,那么就需要设置abstime时间为2021-5-15 17:14:02.600.

2.2 时间获取

条件变量默认使用的时间是CLOCK_REALTIME。通过clock_gettime()接口获取时间。
 

static long long tm_to_ns(struct timespec tm)
{return tm.tv_sec * 1000000000 + tm.tv_nsec;
}static struct timespec ns_to_tm(long long ns)
{struct timespec tm;tm.tv_sec = ns / 1000000000;tm.tv_nsec = ns - (tm.tv_sec * 1000000000);return tm;
}{ 示意代码:struct timespec start_tm;struct timespec end_tm;int timeout_ms = 2500;clock_gettime(CLOCK_REALTIME, &start_tm);end_tm = ns_to_tm(tm_to_ns(start_tm) + timeout_ms*1000000);pthread_mutex_lock(&mtx);while (等待的条件) {if (pthread_cond_timedwait(&cond, &mtx, &end_tm) == ETIMEDOUT) {/** 如果超时则退出等待*/ret = -1;break;}}}

但是CLOCK_REALTIME时间容易产生变化,比如通过NTP校准系统时钟,那么系统时钟会产生跨度变化。所以一般我们需要使用CLOCK_MONOTONIC。

但是条件变量默认使用的时钟是CLOCK_REALTIME,所以需要通过条件变量的属性来设置条件变量使用的时钟。

    pthread_condattr_t attr;pthread_condattr_init(&attr);#if 0clockid_t clock_id;pthread_condattr_getclock(&attr, &clock_id);printf("clock_id: %d\n", clock_id);
#endif/** pthread_cond_timedwait()默认使用的是CLOCK_REALTIME,* CLOCK_REALTIME容易受系统影响,比如校时操作* 所以条件变量使用的时钟改为CLOCK_MONOTONIC* 参考:https://man7.org/linux/man-pages/man3/pthread_cond_timedwait.3p.html*/pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);pthread_cond_init(&cond, &attr);pthread_condattr_destroy(&attr);static long long tm_to_ns(struct timespec tm)
{return tm.tv_sec * 1000000000 + tm.tv_nsec;
}static struct timespec ns_to_tm(long long ns)
{struct timespec tm;tm.tv_sec = ns / 1000000000;tm.tv_nsec = ns - (tm.tv_sec * 1000000000);return tm;
}{ 示意代码:struct timespec start_tm;struct timespec end_tm;int timeout_ms = 2500;clock_gettime(CLOCK_MONOTONIC, &start_tm);end_tm = ns_to_tm(tm_to_ns(start_tm) + timeout_ms*1000000);pthread_mutex_lock(&mtx);while (等待的条件) {if (pthread_cond_timedwait(&cond, &mtx, &end_tm) == ETIMEDOUT) {/** 如果超时则退出等待*/ret = -1;break;}}}

如果想看完整的使用历程可以参考:

Linux应用编程实现简单队列功能_霍宏鹏的博客-CSDN博客

3 描述

pthread_cond_timedwait(3p) - Linux manual page

The pthread_cond_timedwait() and pthread_cond_wait() functions
       shall block on a condition variable. The application shall ensure
       that these functions are called with mutex locked by the calling
       thread; otherwise, an error (for PTHREAD_MUTEX_ERRORCHECK and
       robust mutexes) or undefined behavior (for other mutexes)
       results.

       These functions atomically release mutex and cause the calling
       thread to block on the condition variable cond; atomically here
       means ``atomically with respect to access by another thread to
       the mutex and then the condition variable''. That is, if another
       thread is able to acquire the mutex after the about-to-block
       thread has released it, then a subsequent call to
       pthread_cond_broadcast() or pthread_cond_signal() in that thread
       shall behave as if it were issued after the about-to-block thread
       has blocked.

       Upon successful return, the mutex shall have been locked and
       shall be owned by the calling thread. If mutex is a robust mutex
       where an owner terminated while holding the lock and the state is
       recoverable, the mutex shall be acquired even though the function
       returns an error code.

       When using condition variables there is always a Boolean
       predicate involving shared variables associated with each
       condition wait that is true if the thread should proceed.
       Spurious wakeups from the pthread_cond_timedwait() or
       pthread_cond_wait() functions may occur. Since the return from
       pthread_cond_timedwait() or pthread_cond_wait() does not imply
       anything about the value of this predicate, the predicate should
       be re-evaluated upon such return.

       When a thread waits on a condition variable, having specified a
       particular mutex to either the pthread_cond_timedwait() or the
       pthread_cond_wait() operation, a dynamic binding is formed
       between that mutex and condition variable that remains in effect
       as long as at least one thread is blocked on the condition
       variable. During this time, the effect of an attempt by any
       thread to wait on that condition variable using a different mutex
       is undefined. Once all waiting threads have been unblocked (as by
       the pthread_cond_broadcast() operation), the next wait operation
       on that condition variable shall form a new dynamic binding with
       the mutex specified by that wait operation. Even though the
       dynamic binding between condition variable and mutex may be
       removed or replaced between the time a thread is unblocked from a
       wait on the condition variable and the time that it returns to
       the caller or begins cancellation cleanup, the unblocked thread
       shall always re-acquire the mutex specified in the condition wait
       operation call from which it is returning.

       A condition wait (whether timed or not) is a cancellation point.
       When the cancelability type of a thread is set to
       PTHREAD_CANCEL_DEFERRED, a side-effect of acting upon a
       cancellation request while in a condition wait is that the mutex
       is (in effect) re-acquired before calling the first cancellation
       cleanup handler. The effect is as if the thread were unblocked,
       allowed to execute up to the point of returning from the call to
       pthread_cond_timedwait() or pthread_cond_wait(), but at that
       point notices the cancellation request and instead of returning
       to the caller of pthread_cond_timedwait() or pthread_cond_wait(),
       starts the thread cancellation activities, which includes calling
       cancellation cleanup handlers.

       A thread that has been unblocked because it has been canceled
       while blocked in a call to pthread_cond_timedwait() or
       pthread_cond_wait() shall not consume any condition signal that
       may be directed concurrently at the condition variable if there
       are other threads blocked on the condition variable.

       The pthread_cond_timedwait() function shall be equivalent to
       pthread_cond_wait(), except that an error is returned if the
       absolute time specified by abstime passes (that is, system time
       equals or exceeds abstime) before the condition cond is signaled
       or broadcasted, or if the absolute time specified by abstime has
       already been passed at the time of the call. When such timeouts
       occur, pthread_cond_timedwait() shall nonetheless release and re-
       acquire the mutex referenced by mutex, and may consume a
       condition signal directed concurrently at the condition variable.

       The condition variable shall have a clock attribute which
       specifies the clock that shall be used to measure the time
       specified by the abstime argument. The pthread_cond_timedwait()
       function is also a cancellation point.

       If a signal is delivered to a thread waiting for a condition
       variable, upon return from the signal handler the thread resumes
       waiting for the condition variable as if it was not interrupted,
       or it shall return zero due to spurious wakeup.

       The behavior is undefined if the value specified by the cond or
       mutex argument to these functions does not refer to an
       initialized condition variable or an initialized mutex object,
       respectively.

 

 


http://chatgpt.dhexx.cn/article/0CQYMMeU.shtml

相关文章

Pthread线程基础学习

后面会尝试使用冰搜和goole搜索来学习技术&#xff0c;互联网上知识的学习也是符合二八定律的&#xff0c;既然如此&#xff0c;我们何不去选择最好的文章呢。 文章参考&#xff1a; https://randu.org/tutorials/threads/ http://www.yolinux.com/TUTORIALS/LinuxTutorialPosi…

pthread 线程创建

1.1代码 #include <pthread.h> #include <stdio.h> #include <unistd.h>static int my_thread_func (void *data) {while(1){sleep(1);} }main() {pthread_t tid;int ret;// 1.创建接收线程ret pthread_create(&tid, NULL,my_thread_func, NULL);if(ret…

C语言pthread.h运用

线程概念 什么是多线程&#xff0c;提出这个问题的时候&#xff0c;我还是很老实的拿出操作系统的书&#xff0c;按着上面的话敲下“为了减少进程切换和创建开销&#xff0c;提高执行效率和节省资源&#xff0c;我们引入了线程的概念&#xff0c;与进程相比较&#xff0c;线程…

linux pthread头文件,pthread t 头文件_uint8 t 头文件_pthread t 头文件

多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程。 多线程程序包含可以同时运行的两个或多个部分。这样的程序中的每个部分称为一个线程,每个线程定义了一个单独的执行路径。 本…

Day 55 Linux 线程控制语句pthread_exit pthread_join pthread_detach pthread_cancel 线程属性

目录 1. 线程控制语句 1.1pthread_exit函数 1.2pthread_join函数 1.3pthread_detach函数 1.4pthread_cancel函数 控制原语对比 2. 线程属性 2.1线程属性初始化 2.2线程的分离状态 2.3线程使用注意事项 1. 线程控制语句 1.1pthread_exit函数 将单个当前线程退出 void…

pthread 线程基本函数

文章目录 一、int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);二、int pthread_join(pthread_t tid, void **thread_return);三、int pthread_detach(pthread_t tid);四、void pthread_exit(void *retval);五、int …

pthread

POSIX线程&#xff08;POSIX threads&#xff09;&#xff0c;简称Pthreads&#xff0c;是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统&#xff08;Unix、Linux、Mac OS X等&#xff09;中&#xff0c;都使用Pthreads作为操作系统的线程。 1、p…

线程以及pthread库的使用

一.什么是线程 你可以想象你一边听歌一边打游戏&#xff0c;如果是操作系统会怎么做呢&#xff1f;先执行 ListenMusic 再执行 PlayGame&#xff0c;还是先执行 PlayGame 再执行 ListenMusic 呢&#xff1f;好像都不太合适。为了实现这个目的&#xff0c;就需要引入线程这个概念…

多线程02---pThread简介

1.简介 pthread 是属于 POSIX 多线程开发框架。它是c语言提供的一个跨平台的多线程解决方案。由于其在iOS编程中&#xff0c;操作比较麻烦&#xff0c;一般不用&#xff0c;这里介绍仅仅作为了解。 2.pthread的使用 通过以下函数创建pthread&#xff0c;在C语言中类型的结尾…

Qt 无法识别的外部符号.无法解析的外部符号

原因: 很多博客都说了这个原因,是因为后续在自己的类中,引入Q_OBJECT , 导致vs无法自动生成 moc_XXX.cpp类似的文件, 编译时候,找不到导致的(符号链接). 他人解决办法: 看了很多博客,说用moc_xx.exe, 重新生成对应的.h头文件,一下,就可以了;有的建议重新把类添加一下,然后清…

Qt项目 无法解析的外部符号_WinMainCRTStartup

1、无法解析的外部符号_WinMainCRTStartup 在编译Qt项目的时候突然说找不到_WinMainCRTStartup函数&#xff0c;_WinMainCRTStartup是Qt的主函数。找不到可能是main函数不在工程中。 选中main.cpp点击编译 点击移除再重新添加

QT无法解析的外部符号问题

moc_widget.obj:-1: error: LNK2019: 无法解析的外部符号 "private: void __thiscall Widget::on_pushButton_6_clicked(void)" (?on_pushButton_6_clickedWidgetAAEXXZ)&#xff0c;该符号在函数 "private: static void __cdecl Widget::qt_static_metacall(c…

QT疑难解决:无法解析的外部符号

无法解析的外部符号 _imp_XXXXXXXXX 出现字符_imp&#xff0c;说明不是真正的静态库&#xff0c;而是某个动态库的导入库&#xff0c;导入函数和自己不同名&#xff0c;所以加了字符_imp。 引入相应库 打开MSDN搜索函数xxxxx&#xff1a;http://msdn.microsoft.com/en-us/dn…

CUDA编程时遇到无法解析外部符号threadIdx或blockIdx问题的解决办法

在CUDA编程时遇到出现无法解析外部符号threadIdx或blockIdx问题的解决办法 在CUDA编程之前要确保工程项目的配置属性一致性如图一所示。然后点击项目—>属性确保配置属性无误。 VC 目录 可执行文件目录&#xff1a;…\NVIDIA GPU Computing Toolkit\CUDA\v10.2\bin 包含目…

LNK2019 无法解析的外部符号

LNK 2019 遇到了很多次这个错误&#xff0c;会持续更新遇到该错误产生的原因和解决方法 这个错误是由于我们调用的函数所定义的某个文件在编译时没有正确链接导致的&#xff0c;错误显示如下&#xff1a; 然后根据错误提示找到该函数 ImGui_ImplOpenGL3_Shutdown();ImGui_Impl…

无法解析的外部符号解决方法

步骤1&#xff1a; 按无法解析的顺序来解决问题 比如有两个无法解析&#xff0c;先解决第一个。 步骤2&#xff1a; 点击LNK2001,会跳转到网页&#xff0c;网页会提示哪些无法解析的问题是由哪个无法解析的错误引起的&#xff0c;这样可以减少解决无法解析的错误。 步骤3. …

无法解析的外部符号问题小结

问题1&#xff1a;在编写通信相关程序中&#xff0c;引用了一个静态库&#xff08;该静态库编译没有问题&#xff0c;并被其他项目引用&#xff09;&#xff0c;该库是对SOCKET的一个封装。基本结构如下&#xff1a; 在属性中添加了该库的引用后&#xff0c;编译仍然报错&#…

无法解析的外部符号main

今天在写程序的时候遇到个问题&#xff1a; 然后就去看了相应的解决方法 发现都不管用&#xff1a; 1.不是文件名.c或.cpp的问题 2.不是没有包含相应头文件的问题 3.不是写的控制台程序而使用的Windows连接程序&#xff08;Winmain&#xff09; 最后发现是因为在刚开始打开项…

无法解析的外部符号xxx 该符号在函数xxx中被引用

无法解析的外部符号xxx 该符号在函数xxx中被引用 更多相关错误可查看&#xff1a;https://blog.csdn.net/weixin_44120025/article/details/115279563 下面主要讲述一个解决方案中包含多个项目且它们之间互相引用的情况。 在一个解决方案已经有多个项目的情况下创建一个项目&am…

Visual Studio 2022配置GAMP出现 LNK2019无法解析外部符号_imp_timeGetTime@0

#vs2022配置GAMP 使用visual studio 2022配置软件GAMP的过程可以参考vs2019配置GAMP的详细过程。 在vs2022按照vs2019配置过程后&#xff0c;生成解决方案时&#xff0c;出现了LNK2019 无法解析的外部符号 _imp_timeGetTim0, 函数_tickget中引用了该符号。 解决方法如下&#…