简体   繁体   English

sem_timedwait随机失败

[英]sem_timedwait Fails at Random

I've written a small class that encapsulates shared locks and shared semaphores. 我编写了一个小类,其中封装了共享锁和共享信号灯。 These classes pass all of my unit tests, except for one: about 60% of the time locking a shared memory semaphore using sem_timedwait fails. 这些类通过了我所有的单元测试,除了以下一项:通过sem_timedwait锁定共享内存信号量的时间大约有60%失败。 Here's my code: 这是我的代码:

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;
    }
}

I am able to lock and unlock this semaphore without any errors using sem_wait and sem_trywait; 我可以使用sem_wait和sem_trywait锁定和解锁该信号量,而不会发生任何错误; only sem_timedwait fails randomly. 只有sem_timedwait随机失败。 When it fails it always sets errno to EINVAL. 如果失败,则始终将errno设置为EINVAL。 I am running these tests on Ubuntu Linux 12.10 (64 bit). 我正在Ubuntu Linux 12.10(64位)上运行这些测试。

Could anyone suggest why I am having these problems, and how I may solve them? 谁能说出我为什么遇到这些问题,以及如何解决这些问题?

EINVAL is returned either if sem is not a livad semaphore, or the value of abs_timeout.tv_nsecs is less than 0, or greater than or equal to 1000 million. 如果sem不是livad信号量,或者abs_timeout.tv_nsecs的值小于0或大于或等于10亿,则返回EINVAL

In your case sem should be a valid one, so the possible reason is that the wait.tv_nsec exceeds 1000 million, because it looks possible for the code wait.tv_nsec += ns; 在您的情况下,sem应该是有效的,因此可能的原因是wait.tv_nsec超过了10亿,因为代码wait.tv_nsec += ns; does not check the value. 不检查该值。

You could print its value for debugging purpose, to see if it's the root cause. 您可以打印其值以进行调试,以查看其是否是根本原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM