user2269707
user2269707

Reputation:

Default destructor blocked on a mutex

I got code like below for an experiment:

class Foo {
 public:
  Foo() : mThread(&Foo::test, this) {

  }
 private:
  std::thread mThread;
  std::mutex mMutex;
  std::condition_variable mCv;
  void test() {
    std::unique_lock<std::mutex> lock(mMutex);
    mCv.wait(lock);
  }
};

int main() {
  Foo foo;
  usleep(1000);
  std::cout << "wake up" << std::endl;
}

And the code will block at the destructor of Foo, after debugging, I found out that the thread is blocked on futex_wait, but double check the document of wait() of condition_variable, it says that

At the moment of blocking the thread, the function automatically calls lck.unlock(), allowing other locked threads to continue.

So why my code still blocked at mMutex since mCv has unlocked?

P.S. I know this design pattern has problems, I just curious if I'm missing some knowledge about thread conditions.

Upvotes: 1

Views: 133

Answers (1)

Igor Tandetnik
Igor Tandetnik

Reputation: 52461

Your program exhibits undefined behavior. At the closing brace of main, foo is destroyed, and so are its member variables, beginning with mCv. The standard says:

[thread.condition.condvar]/5

~condition_variable();

Requires: There shall be no thread blocked on *this. [ Note: That is, all threads shall have been notified... —end note ]

Your program violates the Requires clause, as test in another thread waits on mCv and has not been notified.

Upvotes: 2

Related Questions