On 08/10/2010 01:11 PM, Gaetano Mendola wrote:
Hi all, I'm in need to have a reader/writer mutex with no starvation (I'd say a fair mutex), before to make a my own implementation I have checked the boost one to see if it makes starvation or not, and I'm a bit puzzled about the behave:
I'm experiencing this:
reader 1 start ... writer 1 running ... reader 2 start ... writer 2 running ... writer 1 start << blocked reader 3 start << blocked reader 4 start << blocked
until now it seems that reader 3 and reader 4 are waiting because there is a writer waiting and then the writer will run before reader 3 and 4, unfortunately this is not the case, the execution continues like this:
reader 1 ends reader 2 ends ... writer 3 running ... ... writer 4 running ... reader 3 ends reader 4 ends ... writer 1 running ... writer 1 ends
isn't that a waste? Why make reader 3 and 4 waiting and then make those running before the writer? The code to reproduce that is at the end.
Regards Gaetano Mendola
#include <iostream> #include
typedef boost::shared_mutex TMutex; TMutex theMutex;
struct Writer { Writer(const size_t anId) : theId(anId) { }
void operator()() { std::cout << "writer " << theId << " start" << std::endl; boost::unique_lock<TMutex> myLock(theMutex); std::cout << " ... writer " << theId << " running ..." << std::endl; ::sleep(7); std::cout << "writer " << theId << " ends" << std::endl; }
size_t theId; };
struct Reader { Reader(const size_t anId) : theId(anId) { }
void operator()() { std::cout << "reader " << theId << " start" << std::endl; boost::shared_lock<TMutex> myLock(theMutex); std::cout << " ... writer " << theId << " running ..." << std::endl; ::sleep(7); std::cout << "reader " << theId << " ends" << std::endl; }
size_t theId; };
int main (int argc, char** argv) {
Reader r1(1), r2(2), r3(3), r4(4); Writer w(1);
boost::thread myR1(boost::ref(r1)); ::sleep(1); boost::thread myR2(boost::ref(r2)); ::sleep(1); boost::thread myW1(boost::ref(w)); ::sleep(1); boost::thread myR3(boost::ref(r3)); ::sleep(1); boost::thread myR4(boost::ref(r4));
myW1.join(); myR1.join(); myR2.join(); myR3.join(); myR4.join(); }
There is a typo in the reader body it should be "reader running", anyway the problem is the same, readers in wait for a writer are scheduled before the writer then a waste. Regards Gaetano Mendola