mutex :: try_lock()的意外行为

时间:2018-04-23 08:14:03

标签: c++ multithreading

我在程序中尝试了 mutex :: try_lock ()成员,它执行以下操作:

1)故意将并联线程中的互斥锁锁定 2)在主线程中,它尝试使用try_lock()锁定互斥锁    a)如果未获取锁定,则将字符添加到字符串中    b)获取锁定后,将打印字符串。

我已经在2个在线编译器上测试了这个程序:

1)在coliru上,( thread :: hardware_concurrency()为1),程序为here

int main()
{
   /// Lock the mutex for 1 nanosecond.
   thread t {lock_mutex};

   job();

   t.join();
}


/// Lock the mutex for 1 nanosecond.
void lock_mutex()
{
   m.lock();

   this_thread::sleep_for(nanoseconds {1});

   m.unlock();
}


void job()
{
   cout << "starting job ..." << endl;

   int lock_attempts {};

   /// Try to lock the mutex.
   while (!m.try_lock())
   {
      ++lock_attempts;

      /// Lock not acquired.
      /// Append characters to the string.
      append();
   }

   /// Unlock the mutex.
   m.unlock();

   cout << "lock attempts = " << lock_attempts
        << endl;

   /// Lock acquired.
   /// Print the string.
   print();
}


/// Append characters to the string
void append()
{
   static int count = 0;

   s.push_back('a');

   /// For every 5 characters appended,
   /// append a space.
   if (++count == 5)
   {
      count = 0;
      s.push_back(' ');
   }
}


/// Print the string.
void print()
{
   cout << s << endl;
}


这里,程序输出是预期的:

starting job ...

lock attempts = 2444

aaaaa aaaaa aaaaa ...


但是,在这里,如果我从程序中删除以下语句:

   cout << "starting job ..." << endl;

输出显示:

   lock attempts = 0

为什么会这样?


2)另一方面,当我在ideone上尝试这个程序(甚至锁定1秒而不是1纳秒) - here - 我总是得到一个输出显示:

   lock attempts = 0

即使程序中存在诊断“起始作业”,也会发生这种情况。

ideone的 thread :: hardware_concurrency()为8。

换句话说,我立刻成功获得锁定。为什么会这样?

请注意,这不是 try_lock ()虚假失败的情况。在这种情况下,虽然互斥锁上存在 no 现有锁,但该成员返回false,表示锁定尝试失败。

在这里,OPPOSITE似乎正在发生。虽然互斥锁上存在锁(显然),但成员返回true,表示已成功获取新锁!为什么呢?

1 个答案:

答案 0 :(得分:2)

调用cout.operator&lt;&lt; (...)用std :: endl调用flush。这是切换到内核并提供了大量的时间(一些纳秒秒:))以允许lock_mutex线程运行。当您不调用此函数时,lock_mutex尚未启动。 由于调用内核,您甚至可以在单核系统中看到它。