gpt4 book ai didi

multithreading - 原子比较交换。这是正确的吗?

转载 作者:行者123 更新时间:2023-12-03 12:55:56 27 4
gpt4 key购买 nike

我想在某些条件下将1自动添加到计数器,但是我不确定在线程环境中以下操作是否正确:

void UpdateCounterAndLastSessionIfMoreThan60Seconds() const {
auto currentTime = timeProvider->GetCurrentTime();
auto currentLastSession = lastSession.load();
bool shouldIncrement = (currentTime - currentLastSession >= 1 * 60);

if (shouldIncrement) {
auto isUpdate = lastSession.compare_exchange_strong(currentLastSession, currentTime);
if (isUpdate)
changes.fetch_add(1);
}
}

private:
std::shared_ptr<Time> timeProvider;
mutable std::atomic<time_t> lastSession;
mutable std::atomic<uint32_t> changes;

如果两个线程同时求值shouldIncrement = true和isUpdate = true,我也不想多次增加更改(在这种情况下,只有一个应该增加更改)

最佳答案

至少有些不确定,如以下情形所示:

第一个线程1执行以下操作:

auto currentTime = timeProvider->GetCurrentTime();
auto currentLastSession = lastSession.load();
bool shouldIncrement = (currentTime - currentLastSession >= 1 * 60);

然后线程2执行相同的3条语句,但是currentTime比线程1还要多。

然后线程1继续使用它的时间更新 lastSession,该时间小于线程2的时间。

然后线程2轮到了,但是由于线程1已经更改了值,所以无法更新 lastSession

因此最终结果是, lastSession已过时,因为线程2无法将其更新为最新值。在所有情况下,这可能并不重要,情况可能会在不久后得到解决,但这是一个丑陋的角落,可能会破坏某些地方的某些假设,如果不是使用当前代码,则在以后进行一些更改之后。

要注意的另一件事是, lastSessionchnages在原子上不是同步的。其他线程偶尔会看到已更改的 lastSession,但 changes计数器仍未因该更改而增加。同样,这可能无关紧要,但是很容易忘记这样的事情,并意外地编​​写假定它们是同步的代码。

我不能立即确定您是否可以仅使用原子就可以确保100%安全。而是将其包装在互斥锁中。

关于multithreading - 原子比较交换。这是正确的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22947221/

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