gpt4 book ai didi

c++ - 在 C++ 中使用互斥锁时的奇怪行为

转载 作者:行者123 更新时间:2023-11-30 01:51:12 25 4
gpt4 key购买 nike

在调查 C++ (11) 中有关多线程的某些场景时,我遇到了这种(对我而言)奇怪的情况。

我在下面的 2 个线程中运行 increment 函数,传入一个共享变量的地址。核心代码是这样的:

static std::mutex mtx;

static void increment(int *x, int nofIncrements)
{
for (int i = 0; i < nofIncrements; i++)
{
mtx.lock();
(*x)++;
mtx.unlock();
}
}

如您所见,互斥量用于锁定增量操作(效率低下,我知道正确的解决方案是使用原子,但我试图了解发生了什么)。

此代码在 2 个线程中运行,值为 nofIncrements = 100000,这意味着我希望最终值为 200000。但是,有时我会收到无法解释的 200001...

完整类(class)(在本要点中可用 https://gist.github.com/anonymous/4d218dce2a43a06abe6a ):

class LockedIncrement
{
int _nofIncrements;
int _counter;

static std::mutex mtx;

static void increment(int *x, int nofIncrements)
{
for (int i = 0; i < nofIncrements; i++)
{
mtx.lock();
(*x)++;
mtx.unlock();
}
}

public:

LockedIncrement(int nofIncrements)
{
_nofIncrements = nofIncrements;
}

void DoTest()
{
std::thread t1(increment, &_counter, _nofIncrements);
std::thread t2(increment, &_counter, _nofIncrements);
t1.join();
t2.join();
std::cout << "Counter = " << _counter << " (expected " << 2 * _nofIncrements << ")\n";
}
};

测试可以这样运行:

int main(int argc, char* argv[])
{
auto nofIncrements = 1000000;
std::cout << "locked increment \n\n";
auto test = LockedIncrement(nofIncrements);
test.DoTest();
}

最佳答案

gist 中的代码增加了未初始化的 _counter,这会导致不确定的行为。你很幸运得到 200000 和 200001...我得到 377232...

LockedIncrement(int nofIncrements) : 
_nofIncrements( nofIncrements ),
_counter ( 0 )
{
}

关于c++ - 在 C++ 中使用互斥锁时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26454462/

25 4 0