我在程序中尝试了 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/