C++ cpp规范中关于互斥锁try\u lock的错误?

C++ cpp规范中关于互斥锁try\u lock的错误?,c++,C++,在followlink()上,我们声明sample只能返回1到100000之间的值。是否声明0不能在输出中 // mutex::try_lock example #include <iostream> // std::cout #include <thread> // std::thread #include <mutex> // std::mutex volatile int counter (0); // n

在followlink()上,我们声明sample只能返回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;
}
//互斥锁::尝试锁定示例
#include//std::cout
#include//std::thread
#include//std::mutex
易失性整数计数器(0);//非原子计数器
std::mutex mtx;//锁定进入柜台的通道
无效尝试次数增加(){

例如,对于(int i=0;itry\u lock,如果另一个线程持有锁并刚刚释放它,则该锁可能会失败。您读到“在这些情况下,重复调用在某一点上会成功”。为try\u lock执行10000次调用将计为“重复调用”,其中一次将成功。

您永远不会得到0:

当第一次调用
try\u lock()
时(不管哪个线程先在这里),互斥锁被解锁。这意味着10个线程中的1个将成功锁定互斥锁,这意味着
try\u lock()
将成功

您可以获得1:

  • 假设线程0成功锁定互斥锁:

无效尝试次数增加(){

对于(int i=0;i标准规定如下:

30.4.1.2/14[线程.互斥体.要求.互斥体]

实施 即使未被任何其他线程持有,也可能无法获取锁。[注意:此伪故障是 通常不常见,但允许基于简单比较和交换的有趣实现 (第29条)。-尾注]

因此,如果所有的
try\u lock
都失败,您甚至可以得到
0

另外,请不要使用cpluplus.com,它有很多错误。

使用cppreference.com更安全,它是标准的

你会称10000次呼叫为“重复呼叫”吗?啊。虽然如果你很迂腐,网站并没有说0是不可能的。它只是声称1-100000是可能的。我想说,这是全球进步保证的一个边缘案例,很难从语言内部正式化,但是这里有点假设在任何合理的平台上,
try\u lock
的失败意味着其他线程在某个点取得了进展。@kerrek sb为什么站点不声明[0..100000]呢?这是否意味着“错误地失败”可能会发生,但不是在一次首次尝试锁定中?@aefimov:我不知道为什么网站会这么说,我没有写。正如我所说,我认为没有任何真正的硬件上0是一个实际的结果,但我也不认为标准保证了这一点。要获得这个结果,你需要所有线程10000次失败尝试锁定,第1次读取失败9999次,最后一次调用成功。@aefimov第一次调用很可能成功。“当没有其他线程锁定互斥锁时,此函数可能会错误地失败,但在这种情况下,重复调用在某个点上会成功。”我想我的示例有点愚蠢,但我考虑了“在某个点”在我的示例中,第一次出现在thread0
unlock()
之后。但这不太可能。而且我认为,对于10k调用,所有线程都不可能同时失败。这意味着您也可以得到0,但如果我们尊重cplusplus.com上的单词(仅声明值[1..100000]),则声明为不可能:不见了