如何在源代码中强制执行单线程构建

时间:2018-04-24 08:47:56

标签: c++ multithreading

背景:我为一些非常专业的数据处理创建了许多小实用程序。通常,我是唯一的用户。我甚至不考虑多线程编程,因为运行时性能足以满足我的用例。关键资源是我的编程时间。所以我想避免多线程编程所需的额外工作。

然而,当我将来重用我的代码时,似乎存在一个风险,即我的源代码在多线程上下文中执行。

根据CppCoreGuidelines

  

小心:有很多例子是“已知”的代码   永远不会在多线程程序中运行作为一部分运行   多线程程序。经常多年以后。通常,这样的程序   导致删除数据竞赛的痛苦努力。因此,代码就是   从不打算在多线程环境中运行应该是   明确标记为这样,理想情况下是编译或运行时   执法机制,以及早捕捉这些使用错误。

同一来源中的大多数建议实际上让我开始使用多线程编程。我希望遵循的一个建议是:

  

拒绝在多线程环境中构建和/或运行。

所以我的问题是,我该怎么做?例如。是否有一个包含文件,#pragma左右,以确保源文件中的所有内容的单线程构建/执行?

1 个答案:

答案 0 :(得分:5)

使用g++ / gcc编译和链接多线程代码需要使用-pthread编译器和链接器选项。此选项设置_REENTRANT宏,您可以在编译时检查它:

$ g++ -E -dD -xc++ /dev/null > a
$ g++ -pthread -E -dD -xc++ /dev/null > b
$ diff a b
289a290
> #define _REENTRANT 1

与普遍看法相反,使用-lpthread链接器选项是不必要的,不足以正确构建多线程程序。

Microsoft Visual Studio为多线程构建IIRC设置_MT宏。

Boost库执行以下操作:

// Turn on threading support if the compiler thinks that it's in
// multithreaded mode.  We put this here because there are only a
// limited number of macros that identify this (if there's any missing
// from here then add to the appropriate compiler section):
//
#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \
    || defined(_PTHREADS) || defined(__APPLE__) || defined(__DragonFly__)) \
    && !defined(BOOST_HAS_THREADS)
#  define BOOST_HAS_THREADS
#endif

这样您就可以#include <boost/config.hpp>然后检查BOOST_HAS_THREADS宏的值。

如果以多线程模式构建,则会导致编译错误:

#if defined(BOOST_HAS_THREADS) || defined(_REENTRANT) || defined(_MT)
#error This code is single-threaded only.
#endif