- Common pattern in functional programming
- A variable is only initialized when it is first used
- This is useful when the variable is expensive to construct
- e.g. it sets up a network connection
- Can be used in multi-threaded code
- But we need to avoid data races
#include <mutex>
class Test {
public:
void func() { /*...*/ }
};
Test *ptest = nullptr; // Variable to be lazily initialized
std::mutex mut;
void process() {
std::unique_lock<std::mutex> uniq_lck(mut);
if (!ptest)
ptest = new Test;
uniq_lck.unlock();
ptest->func();
}
- Every thread that calls
process() locks the mutex
- Locking the mutex blocks every other thread that calls
process()
- The lock is only needed while
ptest is being initialized
- Once
ptest has been initialized, locking the mutex is unnecessary
- Causes a loss of performance