尽管作用域范围很广,std :: lock_guard似乎仍提供线程安全性

Sri*_*jan 3 c++ concurrency multithreading c++11

mutex m;
void thread_function()
{
    static int i = 0;

    for(int j =0; j<1000; j++)
    {
        { //this scope should make this ineffective according to my understanding
        lock_guard<mutex> lock(m);
        }
        i++;

       cout<<i<<endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

我从2个线程调用此函数。因此,如果函数以线程安全的方式运行,则int i的期望值为1000 * 2 = 2000。

如果没有互斥锁,则打印i时的结果将在1990到2000之间变化(由于非原子int)。在没有作用域块的情况下插入锁保护装置可以防止这种情况。

但是,据我所知,围绕作用域的块应该使其立即获取并释放锁,因此在写入int i时不再具有线程安全性。但是,我注意到我总是2000。我误会了吗?

nie*_*sen 6

您的理解是正确的,并且结果始终2000取决于机器。原因可能是恰好i++在您的计算机上的语句发生之前进行同步,这总是导致线程以足够的时间及时执行该同步以避免竞争情况。但是,如上所述,不能保证。