c++ - 如何使应用程序线程安全?

标签 c++ c multithreading concurrency thread-safety

我特别认为线程安全意味着它必须满足多个线程访问相同共享数据的需要。但是,这个定义似乎还不够。

任何人都可以列出为使应用程序线程安全而要完成或需要注意的事情。如果可能,请给出关于 C/C++ 语言的答案。

最佳答案

有几种方法可以使函数成为线程安全的。

它可以是可重入的。这意味着一个函数没有状态,并且不接触任何全局或静态变量,因此可以同时从多个线程调用它。该术语来自允许一个线程进入函数,而另一个线程已经在其中。

它可以有一个临界区。这个术语经常被抛出,但坦率地说,我更喜欢关键数据。每当您的代码触及跨多个线程共享的数据时,都会出现临界区。所以我更愿意把重点放在关键数据上。

如果您使用 mutex适本地,您可以同步对关键数据的访问,适本地防止线程不安全的修改。互斥锁和锁非常有用,但强大的力量带来了巨大的责任。您不能在同一个线程中两次锁定同一个互斥锁(即自死锁)。如果您获得多个互斥锁,则必须小心,因为这会增加死锁的风险。您必须始终使用互斥锁保护您的数据。

如果您的所有函数都是线程安全的,并且您的所有共享数据都得到适当保护,那么您的应用程序应该是线程安全的。

正如 Crazy Eddie 所说,这是一个巨大的主题。我建议阅读 boost 线程,并相应地使用它们。

低级警告:编译器可以重新排序语句,这会破坏线程安全。对于多核,每个核都有自己的缓存,您需要正确同步缓存以确保线程安全。此外,即使编译器不重新排序语句,硬件也可能。因此,今天实际上不可能实现完全、有保证的线程安全。不过,您可以完成 99.99% 的工作,并且正在与编译器供应商和 cpu 制造商合作解决这个挥之不去的警告。

无论如何,如果您正在寻找一个 list 以使类线程安全:

  • 识别跨线程共享的任何数据(如果错过,则无法保护)
  • 创建一个成员 boost::mutex m_mutex 并在您尝试访问该共享成员数据时使用它(理想情况下,共享数据是类私有(private)的,因此您可以更加确定您的重新正确保护它)。
  • 清理全局变量。无论如何,全局变量很糟糕,祝你好运尝试使用全局变量做任何线程安全的事情。
  • 注意 static 关键字。它实际上不是线程安全的。因此,如果您尝试做一个单例,它将无法正常工作。
  • 注意双重检查锁范式。大多数使用它的人都会以某种微妙的方式弄错它,而且它很容易被低级警告破坏。

这是一个不完整的 list 。如果我想到它,我会添加更多,但希望它足以让你开始。

关于c++ - 如何使应用程序线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5125241/

相关文章:

c - 什么是tcp_autocorking(tcp自动corking)

Android动画减少口吃/断断续续/滞后

java - Java中的读/写锁实现

c++ - 构造函数中抛出的异常 : is the destructor called?

c++ - 如何将 "std::vector<std::string>"转换为 "const char* array"?

c++ - 如何让列表可以隐式转换为我的类对象?

c - 有没有更好的方法来检查 pid 输入是否全是数字?

c - Windows 8.1 上带有 Cygwin 的 ARM GCC : fatal error: no input file

ruby - 杀死通过线程启动的进程

c++ - 类错误的重新定义