我正在尝试使用 sem_timedwait() 重复锁定和解锁信号量。根据此处的示例,我以以下方式将我的 struct timespec 设置为 20 毫秒超时:
sem_t semaphore; //initialized somewhere else
void waitForSomething ()
{
int ret;
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
{
//throw error
}
ts.tv_nsec += 20000000; //timeout of 20 msec
while ((ret = sem_timedwait(&semaphore, &ts)) == -1 && errno == EINTR)
continue;
if (ret == -1 && errno != ETIMEDOUT) {
//flag error
} else {
//do something
}
return;
}
使用上面的代码,我的程序在运行一段时间后会一直失败,并出现 EINVAL 错误代码。调试后,我意识到失败是由于 ts.tv_nsec 在一段时间后超过 1000000000 造成的。我目前的解决方法如下:
sem_t semaphore; //initialized somewhere else
void waitForSomething ()
{
int ret;
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
{
//throw error
}
if (ts.tv_nsec > 979999999) {
ts.tv_sec += 60;
ts.tv_nsec = (ts.tv_nsec + 20000000) % 1000000000;
} else {
ts.tv_nsec += 20000000;
}
while ((ret = sem_timedwait(&semaphore, &ts)) == -1 && errno == EINTR)
continue;
if (ret == -1 && errno != ETIMEDOUT) {
//throw error
} else {
// do something
}
return;
}
我想知道 - 有没有更好的方法来做到这一点而不必自己直接调整 timespec 值?