gpt4 book ai didi

c++ - 使用原子而不是 CriticalSection?

转载 作者:行者123 更新时间:2023-11-30 00:44:47 24 4
gpt4 key购买 nike

我有一段代码可以提供一些数据,对文件等进行一些操作。我使用 1 个线程来提供数据,使用 4 个线程来读取和搜索数据内部。

4 个线程使用文件 vector 进行搜索(使用相同的函数)。为了避免同步问题(所有线程同时读取同一个文件)我使用 CriticalSection() WinAPI:

void ReadData(char* fileName)
{
EnterCriticalSection(&CriticalSection);

// Open file

// Read file data
std::vector<std::string> data;

... Find data inside file

// Close file

LeaveCriticalSection(&CriticalSection);
}

但我看到了这个Post还有这个:

Objects of atomic types are the only C++ objects that are free from data races; that is, if one thread writes to an atomic object while another thread reads from it, the behavior is well-defined.

我的问题是:使用 std::atomic 而不是 CriticalSection 更好吗?或者我想念对原子的用法的理解。

最佳答案

使用标准 C++

在您的代码中,您使用 EnterCriticalSection()LeaveCriticalSection()微软 WinAPI 的功能。

这些有 wto 主要的不便之处:首先它们不可移植,其次它们不安全:如果异常导致线程以意想不到的方式离开 ReadData() 会发生什么?您可能最终会遇到一个在 Windows 看来不会被保留的关键部分,从而使所有其他线程挨饿!

mutex 上使用 lock_guard 的标准 C++ 替代方案,如 Werner 所示, 更安全:首先它可以跨平台移植,但此外,它还实现了 RAII惯用语,它确保如果出现意外异常,lock_guard 在函数离开时被销毁,导致 mutex 被释放。

使用 atomic 可能不够

很多时候,人们很想使用原子,因为他们避免了数据竞争,给人的印象是它将解决所有线程同步问题。

不幸的是,这不是真的。一旦你使用多个原子,你可能会对整体一致性做出假设,而实际上事情可能会发生不同并导致非常讨厌的错误。创建无锁算法和数据结构极具挑战性和难度。因此,我强烈推荐阅读 Anthony William 的优秀著作“C++ concurrency in action”:他深入探讨了所有相关方面。

其他选择

在你的问题中,你提到了一个 vector 。维护并发线程安全 vector 非常困难,因为基本上,无论何时必须扩展 vector 的容量,都可能发生重新分配,从而使指向该 vector 的所有迭代器和指针失效,无论它们在何处使用。幸运的是,有一些线程安全的实现,例如 Microsoft 的 Parallel Pattern Library。 .

另一方面,如果您只使用 vector 来存储文件的行并按顺序处理它们,您不妨考虑使用队列,其优点是能够使用许多线程安全实现之一可用,例如boost .

关于c++ - 使用原子而不是 CriticalSection?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46974599/

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