PDA

View Full Version : QSemaphore's release() does not immediately notify waiters?



PedroCaliente
3rd November 2011, 23:51
I've written a Qt console application to try out QSemaphores and noticed some strange behavior. Consider a semaphore with 1 resource and two threads getting and releasing a single resource. Pseudocode:

QSemaphore sem(1); // init with 1 resource available

thread1()
{

while(1)
{

if ( !sem.tryAquire(1 resource, 1 second timeout) )
{

print "thread1 couldn't get a resource";
}
else
{

sem.release(1);
}
}
}

// basically the same thing
thread2()
{

while(1)
{

if ( !sem.tryAquire(1 resource, 1 second timeout) )
{

print "thread2 couldn't get a resource";
}
else
{

sem.release(1);
}
}
}


Seems straightforward, but the threads will often fail to get a resource. A way to fix this is to put the thread to sleep for a bit after sem.release(1). What this tells me is that the release() member does not allow other threads waiting in tryAquire() access to the semaphore before the current thread loops around to the top of while(1) and grabs the resource again.

This surprises me because similar testing with QMutex showed proper behavior... i.e. another thread hanging out in QMutex::tryLock(timeout) gets notified properly when QMutex::unlock() is called.

Any ideas?