pthread_cond_timedwait函数使用
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.
pthread_cond_timedwait函数使用相关推荐
- Linux C语言 pthread_cond_wait()、pthread_cond_timedwait()函数(不允许cond被唤醒时产生竞争,所以需要和互斥锁搭配)
文章目录 man -f pthread_cond_wait(未看完,待更,,,) pthread_cond_wait:它首先将当前线程加入到唤醒队列,然后旋即解锁mutex,最后等待被唤醒.被唤醒后, ...
- linux c 查看 结构体 宏 函数 关键字定义
在linux c中搜索 结构体 宏定义 关键字 #查找结构体 grep -Rn --include="*.h" --include="*.c" 'struct ...
- 线程模型、pthread 系列函数 和 简单多线程服务器端程序
一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型. (一).N:1用户线程模型 "线程实现"建立在&qu ...
- linux 条件变量函数,Linux线程同步之条件变量
条件变量变量也是出自POSIX线程标准,另一种线程同步机制,.主要用来等待某个条件的发生.可以用来同步同一进程中的各个线程.当然如果一个条件变量存放在多个进程共享的某个内存区中,那么还可以通过条件变量 ...
- Linux系统编程---17(条件变量及其函数,生产者消费者条件变量模型,生产者与消费者模型(线程安全队列),条件变量优点,信号量及其主要函数,信号量与条件变量的区别,)
条件变量 条件变量本身不是锁!但它也可以造成线程阻塞.通常与互斥锁配合使用.给多线程提供一个会合的场所. 主要应用函数: pthread_cond_init 函数 pthread_cond_destr ...
- Linux系统编程----15(线程与进程函数之间的对比,线程属性及其函数,线程属性控制流程,线程使用注意事项,线程库)
对比 进程 线程 fork pthread_create exit (10) pthread_exit (void *) wait (int *) pthread_join (,void **)阻塞 ...
- 【C++】Web服务器项目所用到的函数详解
文章目录 1 Web服务器端监听 1.1 socket()函数 1.2 struct sockaddr和struct sockaddr_in结构体(INADDR_ANY) 1.3 bzero()函数 ...
- [转]Linux 的多线程编程的高效开发经验
Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...
- python3.5全局解释器锁GIL-实现原理浅析
python3全局解释器锁浅谈 本文环境python3.5.2. python全局解释器锁 In CPython, the global interpreter lock, or GIL, is a ...
- Linux多线程之线程同步
线程最大的特点就是资源的共享性,所以也就有了一个难点线程同步,实现线程同步的方法最常用的方法是:互斥锁,条件变量和信号量.接下来就让我们来看下这几种同步的方法. 一.互斥锁(Mutex) 获得锁的线程 ...
最新文章
- 用Unity和Playmaker创建一个限时游戏 Creating a Time Limit game with Unity and Playmaker
- python3 paramiko实现ssh客户端
- AJAX:Getting Started
- wincc无法修改服务器名称_WinCC(TIA)组件SIVARC在BA空调及冷热源系统改造项目中的应用...
- PHP-SESSION深入理解
- html5杂记(1)
- boost::graph模块实现读写graphml的测试程序
- linux arm内核栈切换,ARM Linux中断发生时内核堆栈切换
- altiumer designer学习
- Linux进程全解2——进程环境(环境变量、进程运行的虚拟地址空间)
- 重磅 | 《中国移动云网一体产品白皮书(2021)》发布!
- xtrabackup备份脚本
- Jenkins与代码上线解决方案
- qt 工具栏分隔符_带有分隔线和上下文工具栏的RecyclerView Android
- WordPress W3 Super Cache插件远程PHP代码执行漏洞
- 关于np.meshgrid
- Sublime text 2 无需注册码的破解方法,只改2个字节
- windows 超简单实现多用户远程桌面,RDP WRAPPER
- 甲骨文中国裁员行动反映了什么问题?
- 惠普打印机墨盒更换教程_惠普打印机换墨盒图解 惠普打印机怎么换墨盒