Advanced Programming in UNIX Environment Episode 60
发布日期:2021-10-07 23:47:38 浏览次数:2 分类:技术文章

本文共 3144 字,大约阅读时间需要 10 分钟。

#include "apue.h"#include 
#include
#include
extern int makethread(void *(*)(void *), void *);struct to_info{ void (*to_fn)(void *); void *to_arg; struct timespec to_wait;};#define SECTONSEC 100000000000#if !defined(CLOCK_REALTIME)||defined(BSD)#define clock_nanosleep(ID,FL,REQ,REM) nanosleep((REQ),(REM))#endif#ifndef CLOCK_REALTIME#define CLOCK_REALTIME 0#define USECTONSEC 1000void clock_gettime(int id, struct timespec *tsp){ struct timeval tv; gettimeofday(&tv,NULL); tsp->tv_sec=tv.tv_sec; tsp->tv_nsec=tv.tv_usec*USECTONSEC;}#endifvoid *timeout_helper(void *arg){ struct to_info *tip; tip=(struct to_info*)arg; clock_nanosleep(CLOCK_REALTIME,0,&tip->to_wait,NULL); (*tip->to_fn)(tip->to_arg); free(arg); return 0;}void timeout(const struct timespec *when, void (*func)(void *), void *arg){ struct timespec now; struct to_info *tip; int err; clock_gettime(CLOCK_REALTIME,&now); if((when->tv_sec>now.tv_sec)|| (when->tv_sec==now.tv_sec&&when->tv_nsec>now.tv_nsec)) { tip=malloc(sizeof(struct to_info)); if(tip!=NULL) { tip->to_fn=func; tip->to_arg=arg; tip->to_wait.tv_sec=when->tv_sec-now.tv_sec; if(when->tv_nsec>=now.tv_nsec) { tip->to_wait.tv_nsec=when->tv_nsec-now.tv_nsec; } else { tip->to_wait.tv_sec--; tip->to_wait.tv_nsec=SECTONSEC-now.tv_nsec+when->tv_nsec; } err=makethread(timeout_helper,(void *)tip); if(err==0) return ; else free(tip); } } (*func)(arg);}pthread_mutexattr_t attr;pthread_mutex_t mutex;void retry(void *arg){ pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex);}int main(void){ int err, condition, arg; struct timespec when; if((err=pthread_mutexattr_init(&attr))!=0) err_exit(err,"pthread_mutexattr_init failed"); if((err=pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))!=0) err_exit(err, "can't set recursive type"); pthread_mutex_lock(&mutex); if(condition) { clock_gettime(CLOCK_REALTIME, &when); when.tv_sec+=10; timeout(&when, retry, (void *)((unsigned long)arg)); } pthread_mutex_unlock(&mutex); return 0;}

Using a recursive mutex

We could call sleep to wait for the timeout to expire, but that gives us only second granularity. If we want to wait for some time other than an integral number of seconds, we need to use nanosleep or clock_nanosleep, both of which allow us to sleep at higher resolution.

On systems that don’t define CLOCK_REALTIME, we define clock_nanosleep in terms of nanosleep. However, FreeBSD 8.0 defines this symbol to support clock_gettime and clock_settime, but doesn’t support clock_nanosleep (only Linux 3.2.0 and Solaris 10 currently support clock_nanosleep.)

Additionally, on systems that don’t define CLOCK_REALTIME, we provide our own implementation of clock_gettime that calls gettimeofday and translates microseconds to nanoseconds.

转载地址:https://blog.csdn.net/myfather103/article/details/79967391 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Advanced Programming in UNIX Environment Episode 61
下一篇:Advanced Programming in UNIX Environment Episode 59

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月22日 01时16分02秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章