
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 <boost/thread.hpp> 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(); }