C ++ Thread Safe Lazy Load

I have a property similar to the following:

private: Foo* myFoo_m; public: Foo getMyFoo() const { if (myFoo_m == NULL) { myFoo_m = new Foo(); // perform initialization 

This works well in a single-threaded environment, but how can I handle this in a multi-threaded environment? Most of the information I found relates to static singlets, but in this case, myFoo is a public instance property.

I port this with C # (where I can use Lazy) and Java (where I can use double check lock), but there seems to be no easy way to do this in C ++. I can not rely on external libraries (without BOOST), and this is necessary for working with windows and linux. I also can not use C ++ 11.

Any insight would be good. I am new to C ++.

+4
source share
3 answers

If you have access to C ++ 11 , you can use std::mutex to block preventing multiple threads from initializing a lazy partition. (Note: std::mutex only became available on Windows with VS2012)

You can even grab a mutex using std::lock_guard :

 private: std::mutex m_init_mutex; public: Foo getMyFoo() const { { std::lock_guard<std::mutex> lock(m_init_mutex); if (myFoo_m == NULL) { myFoo_m = new Foo(); // perform initialization } } 

EDIT : OP now stated that C ++ 11 is not an option, but perhaps this answer will be useful in the future

+5
source

Saying "no C ++ 11", "no Boost or other third-party code", "should work on Windows and Linux", you limited yourself to using implementation-specific locking mechanisms.

I think your best option is to define a simple locking class for yourself and implement it for using pthread_mutex on Linux and CriticalSection on Windows. Perhaps you already have some platform-specific code to start streams in the first place.

You can try something like Windows Services for UNIX to avoid writing platform-specific code, but it's probably not worth it for a single lock. And although it comes from Microsoft, you probably consider it an external library.

+4
source

Warning: I did not see the requirement "no C ++ 11", so please do not pay the answer to them.


Since C ++ 11 requires that the static initialization of variables be thread safe, here is a simple way that you might consider "cheating":

 Foo init_foo() { // initialize and return a Foo } Foo & get_instance_lazily() { static Foo impl = init_foo(); return impl; } 

The instance will be initialized the first time you call get_instance_lazily() , and is thread-safe.

+1
source

Source: https://habr.com/ru/post/1443686/


All Articles