Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enforce single threaded build in source code

Background: I create many small utilities for some very specialised data processing. Often, I am the only user. I don't even think about multi-threaded programming, because the run-time performance is by far sufficient for my use cases. The critical resource is my programming time. So I want to avoid any extra effort required for multi-threaded programming.

However, it seems there is a risk, that my source code gets executed in a multi-threaded context, when I reuse my code in future.

According to CppCoreGuidelines :

Be careful: there are many examples where code that was “known” to never run in a multi-threaded program was run as part of a multi-threaded program. Often years later. Typically, such programs lead to a painful effort to remove data races. Therefore, code that is never intended to run in a multi-threaded environment should be clearly labeled as such and ideally come with compile or run-time enforcement mechanisms to catch those usage bugs early.

Most of the suggestions in the same source actually get me started with multi-threaded programming. The one suggestion, which I prefer to follow says:

Refuse to build and/or run in a multi-threaded environment.

So my question is, how do I do that? E.g. is there an include file, #pragma or so to ensure single threaded build / execution of everything within a source file?

like image 329
Kağan Kayal Avatar asked Apr 24 '18 08:04

Kağan Kayal


1 Answers

With g++/gcc compiling and linking multithreaded code requires using -pthread compiler and linker option. This option sets _REENTRANT macro which you can inspect at compile time:

$ c="g++ -E -dD -xc++ /dev/null"
$ diff <($c) <($c -pthread)
389a390
> #define _REENTRANT 1

Contrary to popular belief, using -lpthread linker option is unnecessary and insufficient to correctly build a multi-threaded program.


Microsoft Visual Studio sets _MT macro for a multi-threaded build, IIRC.


Boost library does the following:

// 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

So that you can #include <boost/config.hpp> and then inspect the value of BOOST_HAS_THREADS macro.


The following causes a compilation error if it is built in multi-threaded mode:

#if defined(BOOST_HAS_THREADS) || defined(_REENTRANT) || defined(_MT)
#error This code is single-threaded only.
#endif
like image 61
Maxim Egorushkin Avatar answered Sep 19 '22 16:09

Maxim Egorushkin