我编写了一个封装共享锁和共享信号量的小类。这些类通过了我的所有单元测试,除了一个:大约60%的时间使用sem_timedwait锁定共享内存信号量失败。这是我的代码:
SharedLock::SharedLock(const SharedSemaphore& semaphore, unsigned int wait_ns) :
Succeeded(false),
Semaphore(semaphore)
{
timespec wait;
if(clock_gettime(CLOCK_REALTIME, &wait) < 0)
{
throw exception_ty(SHARED_LOCK_RUNTIME_ERROR,
"SharedLock::SharedLock(...) failed: clock_gettime(...) encountered an error.");
}
unsigned long ns = wait_ns % 1000000000;
wait.tv_sec += (wait_ns - ns) / 1000000000;
wait.tv_nsec += ns;
int result = sem_timedwait(const_cast<sem_t*>(Semaphore.Semaphore.get_data()), &wait);
if(result < 0 && errno != ETIMEDOUT)
{
throw_on_sem_wait();
}
else if(result == 0)
{
Succeeded = true;
}
}
我可以使用sem_wait和sem_trywait锁定和解锁此信号量而不会出现任何错误;只有sem_timedwait随机失败。当它失败时,它总是将errno设置为EINVAL。我在Ubuntu Linux 12.10(64位)上运行这些测试。
有人能说明我遇到这些问题的原因,以及我如何解决这些问题?
答案 0 :(得分:3)
EINVAL
。
在你的情况下,sem应该是有效的,所以可能的原因是wait.tv_nsec
超过了10亿,因为代码wait.tv_nsec += ns;
看起来可能没有检查值。
您可以打印其值以进行调试,以查看它是否是根本原因。