Trying to use a function static mutex to make code thread safe. The problem is not all compilers initialize function static variables in a thread safe way.
void Initialize()
{
static Mutex L; // can't be initialized at compile time because constructor calls CreateMutex()
L.Lock()
// call thread unsafe code
L.Unlock()
}
Here are solutions already considered:
Declare Mutex in global scope so that initialization happens before main(). Unfortunately, this doesn't work when there's a global variable whos constructor calls Initialize() because in C++ there's no guarantee about the order global variables are initialized
Use atomic operations
void Initialize() { static volatile uint16_t lock=0; // trivial initialization can happen @ compile time while (AtomicExchange(lock,(uint16_t)1)!=0); // swap lock with 1 and return previous value // call thread unsafe code lock=0; }
This works but has the disadvantage of busy waiting
Use pthread's compile time initializer
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
Unfortunately, this is for Windows, and we're trying to avoid using pthread
Appreciate a solution that's portable . I know in C++ 2011, function static initialization is thread safe, but we're avoiding C++ 2011 because some embedded platforms might have unreliable C++ 2011 support.
IMO the solution to your problem is to use a nifty counter idiom. This idiom is very well described here: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter .
Using this idiom std::cout
, std::cerr
, std::clog
streams are initialized. The only requirement is that you need to properly calculate the alignment of created type. Using that alignment you need to create a global buffer. Using that buffer the instance of the desired type with the placement new operator can be created. Boost and Modern C++ (>= C++11) have (std|boost)::aligned_storage
template classes to create a properly aligned buffer for you. Please refer to:
Modern versions of C++ feature the alignof
operator, which can be used to calculate the alignment of a particular type. In boost you need to use a type trait alignment_of
: https://www.boost.org/doc/libs/1_69_0/libs/type_traits/doc/html/boost_typetraits/reference/alignment_of.html . alignment_of
type trait is also part of STL in modern C++, but in that particular case alignof
operator is simpler to use.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.