К сожалению, я думаю, что единственный способ избежать этого - использовать непортативные одноразовые директивы инициализации и вообще избежать разрушения блокировки.Необходимо решить две основные проблемы:
- Что произойдет, если два потока впервые получат доступ к блокировке?[то есть, вы не можете лениво создать блокировку]
- Что произойдет, если блокировка будет разрушена слишком рано?[то есть вы не можете статически создать блокировку]
Комбинация этих ограничений заставляет вас использовать непереносимый механизм для создания блокировки.
На pthreads наиболееПростой способ справиться с этим - PTHREAD_MUTEX_INITIALIZER
, который позволяет статически инициализировать блокировки:
class LibLoader{
static pthread_mutex_t mutex;
// ...
};
// never destroyed
pthread_mutex_t LibLoader::mutex = PTHREAD_MUTEX_INITIALIZER;
В Windows вы можете использовать синхронную однократную инициализацию .
В качестве альтернативы, если вы можете гарантировать, что перед основными запусками будет только один поток, вы можете использовать шаблон синглтона без разрушения и просто принудительно коснуться блокировки перед main ():
class LibLoader {
class init_helper {
init_helper() { LibLoader::getLock(); }
};
static init_helper _ih;
static Lock *_theLock;
static Lock *getLock() {
if (!_theLock)
_theLock = new Lock();
return _theLock;
}
// ...
};
static init_helper LibLoader::_ih;
static Lock *LibLoader::_theLock;
Обратите внимание, что это делает, возможно, непереносимым (но весьма вероятным истинным) предположение о том, что статические объекты типа POD не уничтожаются до тех пор, пока не будут уничтожены все не-POD статические объекты.Я не знаю ни одной платформы, в которой это не так.