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 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 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來判斷呢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM