• 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
    ", 24);
        if (sem_post(&sem) == -1) {
            write(STDERR_FILENO, "sem_post() failed
    ", 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>
    ",
                    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()
    ");
        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
    ");
            else
                perror("sem_timedwait");
        } else
            printf("sem_timedwait() succeeded
    ");
    
       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来判断呢。

  • 相关阅读:
    REDELK的安装和使用
    Palo Alto GlobalProtect上的PreAuth RCE
    渗透 Facebook 的思路与发现
    抓取腾讯视频MP4文件
    JS中整数的取整、取余、向上取整
    centos7安装docker
    业界难题-“跨库分页”的四种方案(转)
    centos7设置时间
    简单实现Shiro单点登录(自定义Token令牌)
    nginx 反向代理时丢失端口的解决方案(转)
  • 原文地址:https://www.cnblogs.com/coding-my-life/p/4085336.html
Copyright © 2020-2023  润新知