why doesn't locking a mutex in one thread not block locking the same mutex in a different thread?

StackOverflow https://stackoverflow.com/questions/23548303

  •  18-07-2023
  •  | 
  •  

Question

Basically, I don't understand why this code runs. I was of the belief that locking a mutex would cause other attempts to lock the mutex to block, but that doesn't seem to be the case.

#include <cstdio>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

class Foo 
{
  public:
  Foo()
  {
    pThread = boost::make_shared< boost::thread >( [=](){
      boost::unique_lock< boost::mutex >( mtx );
      while( true )
      {   
        fprintf( stdout, "I have the mutex\n");
      }   
    } );
  }

  void bar()
  {
    boost::unique_lock< boost::mutex >( mtx );
    fprintf( stdout, "bar got the mutex\n");
  }

  private:
  boost::mutex mtx;
  boost::shared_ptr< boost::thread > pThread;
};

int main()
{
  Foo foo;
  while( true )
  {
    foo.bar();
  }
}

edit: Output after adding some sleeps so the output is managable.

bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
bar got the mutex
I have the mutex
^C

This is different from what I reported earlier and this is the updated code. I'm not sure how sleeping threads would affect the output though.

#include <cstdio>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

class Foo 
{
  public:
  Foo()
  {
    pThread = boost::make_shared< boost::thread >( [=](){
      boost::unique_lock< boost::mutex >( mtx );
      while( true )
      {   
        boost::this_thread::sleep( boost::posix_time::milliseconds( 1000 ) );
        fprintf( stdout, "I have the mutex\n");
      }   
    } );
  }

  void bar()
  {
    boost::unique_lock< boost::mutex >( mtx );
    fprintf( stdout, "bar got the mutex\n");
  }

  private:
  boost::mutex mtx;
  boost::shared_ptr< boost::thread > pThread;
};

int main()
{
  Foo foo;
  while( true )
  {
    boost::this_thread::sleep( boost::posix_time::milliseconds( 1000 ) );
    foo.bar();
  }
}
Was it helpful?

Solution

You are not even locking mutex.

boost::unique_lock< boost::mutex >( mtx );

It is parsed as declaration of variable mtx with type boost::unique_lock< boost::mutex >, initialized with default constructor. Instead you need to use constructor that takes reference to lockable object:

boost::unique_lock< boost::mutex > lock{mtx};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top