首页 > 代码库 > sem_timedwait的用法

sem_timedwait的用法

       #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 voidhandler(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);    }}intmain(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 current 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来判断呢。

sem_timedwait的用法