gpt4 book ai didi

c++ - 如何正确序列化线程访问控制循环的标志

转载 作者:行者123 更新时间:2023-11-28 06:27:46 26 4
gpt4 key购买 nike

我有一个函数 f1,它包含一个简单的循环,它通过 bool 标志进行控制。该标志未写入 f1 内部。

我有另一个清除标志的函数。

这两个函数在不同的线程上调用。

如果我在进入 f1 循环之前锁定互斥锁,那么 f2 将无法获取它以清除标志。

如果我在进入 f1 中的循环之前不锁定互斥量,则该标志不 protected 。考虑到函数只读取它,这有关系吗?

我的问题是我是否需要在进入 f1 循环之前保护标志,因为它只被读取?如果是这样,如何?

如果标志只写在一个地方,我还需要互斥量吗?

我是否遗漏了一些基本的东西?

TIA

class X
{
public:
X() :
m_thread(),
m_isDone(false),
m_mutex()
{
m_thread = std::unique_ptr<std::thread>(new std::thread( [=]{ run(); } ));
}

~X()
{
// tell the thread to exit
m_isDone = true;

// wait for the thread to terminate
m_thread->join();
}

void f1()
{
// locking the mutex will prevent f2 from clearing the flag
std::lock_guard<std::mutex> lock(m_mutex);

while (!m_isDone)
{
// do some stuff
}
}

void f2()
{
// lock the mutex
std::lock_guard<std::mutex> lock(m_mutex);
m_isDone = true;
}

private:
std::unique_ptr<std::thread> m_thread;
bool m_isDone;
mutable std::mutex m_mutex;
};

最佳答案

只是改变:

bool m_isDone;

到:

std::atomic<bool> m_isDone;

这将使您对 m_isDone 的读取和写入保证原子性(您需要这样做,因为它是在不同的线程中读取和写入的)。 atomic 还避免了对任何类型的互斥锁、锁等的需要。

请注意,在您的解决方案中,f1 永远 持有锁,因此 f2 永远无法获取它。带锁的正确解决方案更加复杂且不必要:

bool isDone() { // easily replaced by atomic load
std::lock_guard<std::mutex> lock(m_mutex);
return m_isDone;
}

void f1() {
while (!isDone()) {
// stuff
}
}

关于c++ - 如何正确序列化线程访问控制循环的标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28220991/

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