您的位置:首页 > 大数据 > 人工智能

sem_timedwait的用法

2016-05-16 14:33 1746 查看
#include <semaphore.h>

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

Link with -pthread.


  对于这个函数,主要在于abs_timeout这个参数。一开始我以为是传入需要等待的时间。像这样:

struct timespec ts;
ts.tv_nsec = 1000;
ts.tv_sec   = 10;
sem_timedwait(p_sem, &ts);


意思是我希望10秒1000纳秒才超时。结果,函数立即返回。网上查一下资料,才知道我错得多么离谱。这个abs_timeout竟然是UTC时间戳。看下面的代码http://linux.die.net/man/3/sem_timedwait:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>

sem_t sem;

#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

static void
handler(int sig)
{
write(STDOUT_FILENO, "sem_post() from handler\n", 24);
if (sem_post(&sem) == -1) {
write(STDERR_FILENO, "sem_post() failed\n", 18);
_exit(EXIT_FAILURE);
}
}

int
main(int argc, char *argv[])
{
struct sigaction sa;
struct timespec ts;
int s;

if (argc != 3) {
fprintf(stderr, "Usage: %s <alarm-secs> <wait-secs>\n",
argv[0]);
exit(EXIT_FAILURE);
}

if (sem_init(&sem, 0, 0) == -1)
handle_error("sem_init");

/* Establish SIGALRM handler; set alarm timer using argv[1] */

sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGALRM, &sa, NULL) == -1)
handle_error("sigaction");

alarm(atoi(argv[1]));

/* Calculate relative interval as cu
4000
rrent time plus
number of seconds given argv[2] */

if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
handle_error("clock_gettime");

ts.tv_sec += atoi(argv[2]);

printf("main() about to call sem_timedwait()\n");
while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
continue;       /* Restart if interrupted by handler */

/* Check what happened */

if (s == -1) {
if (errno == ETIMEDOUT)
printf("sem_timedwait() timed out\n");
else
perror("sem_timedwait");
} else
printf("sem_timedwait() succeeded\n");

exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
}


在这段代码中,他没有处理溢出,下面是我的代码:

int32 CSeamphoreLock::time_lock( int32 nano_sec,int32 sec )
{
struct timespec ts;

if ( clock_gettime( CLOCK_REALTIME,&ts ) < 0 )
return -1;

ts.tv_sec  += sec;
ts.tv_nsec += nano_sec;

//#define NSECTOSEC    1000000000
ts.tv_sec += ts.tv_nsec/NSECTOSEC; //Nanoseconds [0 .. 999999999]
ts.tv_nsec = ts.tv_nsec%NSECTOSEC;

return sem_timedwait( m_psem,&ts );
}


  PS:居然用的时间戳,如果正在等待的时候管理员调整时间会不会让某个程序出问题呢??为什么不用clock_gettime的CLOCK_MONOTONIC来判断呢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: