gpt4 book ai didi

c++ - 互斥锁和 block 作用域

转载 作者:行者123 更新时间:2023-11-28 05:16:47 27 4
gpt4 key购买 nike

在代码中使用互斥量:

class Bank{
public:
Bank():counter(0){};
void addBankAccount(){
unique_lock<mutex> m ( g_Mtx );
for( int i = 0; i < 1000; i++){
counter++;
}
}

int getCounter(){
return counter;
}

private:
int counter;
mutex g_Mtx;
};


int calculate(){
Bank b;
thread t1(&Bank::addBankAccount,&b);
thread t2(&Bank::addBankAccount,&b);
t1.join();
t2.join();
if( b.getCounter() != 2000)
cout << "Error value is " << b.getCounter() << endl;
}

int main()
{
for(int i = 0; i < 10000; i++)
calculate();
return 0;
}

为了保持正确的结果,互斥锁本身是必需的。如果没有互斥锁我没记错的话,它会产生一些结果:

      THREAD 1                           |              THREAD 2
|
1) load value of counter in register | 2) load value of counter in register
value in register is 0 | value in register is 0

3) increment register( value is 1) | 4) increment register( value is 1)

4) update variable, value of | 5) update variable, value of
counter is set to 1 again counter is set to 1

( marking 1)... 5) 应该指出指令可以被计算机处理的顺序 ) 因此省略了一些增量。但我的问题是关于互斥锁本身。

当两个线程同时运行时,例如同一个函数

void addBankAccount(){
unique_lock<mutex> m ( g_Mtx );
for( int i = 0; i < 1000; i++){
counter++;
}
}

在我的理解中,当声明互斥锁并锁定锁时,想要访问锁中保存的数据的线程会“暂停”并在锁解锁时“恢复”并且它可以访问数据(想要使用该数据的线程在队列中)。但是当 mutex 在另一个 block 范围内时会发生什么?例如:

    void addBankAccount(){
{
unique_lock<mutex> m ( g_Mtx );
for( int i = 0; i < 1000; i++){
counter++;
}
// some other piece of code
}

这会改变什么吗?我已经看到了这种用法,但我看不出它与函数的原始声明有何不同。当线程想要访问被锁定的数据时,它是“暂停”整个线程,还是只“暂停” block 范围,所以在这种情况下它会跳转到

 // some other piece of code

当锁被解锁时,它会跳回作用域内的循环吗?

我已经阅读了很多关于互斥锁的文章,但我仍然对此感到困惑。

还有 ofc,我对互斥量的理解可能是错误的。

感谢所有解释。

谢谢

最佳答案

在您的示例中,没有区别。将锁嵌入内部 block 的原因是,可以尽早释放互斥锁。

void addBankAccount(){
int count_save;
{
unique_lock<mutex> m ( g_Mtx );
for( int i = 0; i < 1000; i++){
counter++;
}
count_save = counter;
} // mutex will be released here

// Still inside addBankAccount, but now it's safe to do IO
std::cout << "Bank account is now" << count_saved;
}

你经常发现你想释放一个互斥锁,然后做一些其他的处理。比如IO速度慢,涉及获取其他锁;持有互斥量时最好不要这样做。

请注意,在示例中,count_save 是一个局部变量,因此是线程私有(private)的 - 它不是受互斥锁保护的共享状态的一部分。一旦互斥锁被释放,就不要触及任何共享状态,这一点很重要。

另请注意,由于缺乏同步,帐户状态可能在输出发生之前已更改。事实上,无法保证较早更改的输出会在较晚更改的输出之前发生。 (因此,这可能不是一个特别好的例子!)

关于c++ - 互斥锁和 block 作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42472031/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com