Boost logo

Boost Users :

Subject: Re: [Boost-users] [Thread] Writer/Reader strange scheduling
From: Gaetano Mendola (mendola_at_[hidden])
Date: 2010-08-10 08:48:29


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

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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net