首页 > 解决方案 > IPC:每秒从客户端收集数据

问题描述

我想从连接到我的服务器的所有客户端收集数据,我想最多等待 1 秒。如何用信号量做到这一点?我当前的代码:

int players=2;
while(1){
    //request for choice
    for(int i = 0; i<players; i++)
        sem_post(&sharedMemory->request_choice);
    //wait for data
    for (int i = 0;i<players; i++)
        //ok..I have data but not in 1 second..
        sem_wait(&sharedMemory->got_choice);


    //updating data..
}

标签: cpthreadssemaphore

解决方案


POSIX 平台提供sem_timedwait()

概要

#include <semaphore.h>
#include <time.h>

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

描述

该函数应锁定函数中 assem_timedwait()引用的信号量 。但是,如果在不等待另一个进程或线程通过执行某个功能来解锁信号量的情况下无法锁定信号量,则应在指定的超时时间到期时终止该等待。semsem_wait()sem_post()

超时将在 abstime 指定的绝对时间过去时到期,由超时所基于的时钟测量(即,当该时钟的值等于或超过时abstime),或者如果指定的绝对时间abstime已经过去通话时间。

超时应基于CLOCK_REALTIME时钟。超时的分辨率应该是它所基于的时钟的分辨率。数据类型在标头timespec中定义为结构<time.h>

如果可以立即锁定信号量,则在任何情况下功能都不会因超时而失败。abstime 如果可以立即锁定信号量,则无需检查其有效性。

返回值

sem_timedwait()如果调用进程成功地对由 指定的信号量执行信号量锁定操作,则该函数应返回零sem。如果调用不成功,信号量的状态应保持不变,函数应返回一个值-1并设置errno为指示错误。

错误

如果出现以下情况,该sem_timedwait()功能将失败:

...

[ETIMEDOUT]
    The semaphore could not be locked before the specified timeout expired.

该链接还提供了此示例用法:

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


if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
    perror("clock_gettime");
    exit(EXIT_FAILURE);
}
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 */

推荐阅读