在关注链接(http://www.cplusplus.com/reference/mutex/mutex/try_lock/)上,我们声明样本只能返回1到100000之间的值。是否声明0不能输出?
// mutex::try_lock example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
volatile int counter (0); // non-atomic counter
std::mutex mtx; // locks access to counter
void attempt_10k_increases () {
for (int i=0; i<10000; ++i) {
if (mtx.try_lock()) { // only increase if currently not locked:
++counter;
mtx.unlock();
}
}
}
int main ()
{
std::thread threads[10];
// spawn 10 threads:
for (int i=0; i<10; ++i)
threads[i] = std::thread(attempt_10k_increases);
for (auto& th : threads) th.join();
std::cout << counter << " successful increases of the counter.\n";
return 0;
}
在任何情况下,很容易回答'如何获得2?',但真的不清楚如何获得1而永远不会得到0。
当没有其他线程在互斥锁上有锁时,try_lock可以“虚假失败,但在这些情况下重复调用在某些时候会成功”,但如果是,则样本可以返回0(并且也可以返回1)某些情况)。
但是,如果此规范示例声明为true且0不能输出,那么关于“虚假失败”的单词可能不是真的那么?
答案 0 :(得分:2)
标准说明如下:
30.4.1.2/14 [thread.mutex.requirements.mutex]
实施 即使它没有被任何其他线程持有,也可能无法获得锁定。 [注意:这种虚假的失败是 通常不常见,但允许基于简单比较和交换的有趣实现 (第29条)。 - 后注]
如果所有0
都失败,您甚至可以获得try_lock
。
另外,请不要使用cplusplus.com,它有long history有很多错误。
使用cppreference.com比标准much closer更安全。
答案 1 :(得分:1)
try_lock可能会失败。你读到了这些情况&#34;在这些情况下重复的电话会在某些时候成功#34;对try_lock进行10,000次调用将计为&#34;重复调用&#34;其中一个会成功。
答案 2 :(得分:-1)
你永远不会得到0:
当第一次调用try_lock()
时(首先是哪个线程无关紧要),互斥锁将被解锁。这意味着10个线程中的1个将设法锁定互斥锁,这意味着try_lock()
将成功。
你可以获得1:
void attempt_10k_increases () {
for (int i=0; i<10000; ++i) {
if (mtx.try_lock()) { // thread 1 to 9 are here
++counter; // thread 0 is here
mtx.unlock();
}
}
}
现在我们说操作系统调度程序选择不运行线程0一段时间。在此期间,线程1到9继续运行,调用try_lock()
并失败,因为线程0保存互斥锁。