c++ - mutex::try_lock() 的意外行为

标签 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

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

ideone 的 thread::hardware_concurrency() 为 8。

也就是说,我马上就成功拿到了锁。为什么会这样?

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

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

最佳答案

用 std::endl 调用 cout.operator << (...) 调用 flush。这是一个切换到内核并提供大量时间(几纳秒 :) )来允许 lock_mutex 线程运行。当您不调用此函数时,lock_mutex 尚未启动。 由于对内核的调用,您甚至可能会在单核系统中看到这一点。

关于c++ - mutex::try_lock() 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49976317/

相关文章:

C++ 无法为高阶函数派生模板参数

c++ - 在 CPP 中初始化一个 2 Dimensional vector<int>

c++ - 使用 decltype 将其转换为 const

java - 使用DelayQueue异步执行任务: postponing an already submitted task

c++ - 尝试在 C++11 线程中使用已删除的函数

python 3 : How to properly add new Futures to a list while already waiting upon it?

c++ - Windows 7 上的 Emacs 构建过程

c++ - 带有格式化字符串的 istream 提取值

c# - 使用多线程更快地读取文件?

Java如何同步2个线程?