Короче говоря, я бы хотел, чтобы определенный фрагмент статической инициализации происходил как можно ближе к началу main () / DllMain (). Вероятно, было бы приемлемо, чтобы это был конструктор, вызываемый последним во время статической инициализации.
Поскольку это почти наверняка будет реализация, специфичная для компилятора, я специально собираюсь сделать это с помощью компилятора Visual C ++ (VS 2010 и выше). В будущем мне, вероятно, нужно будет сделать это в GCC и Clang, но это не является непосредственной проблемой.
Длинная история состоит в том, что у меня есть объект в базовой библиотеке, который статически инициализируется и создает поток в своем конструкторе. Этот поток опирается на другие статически инициализированные объекты в библиотеках, которые мы не контролируем, поэтому он вызывает состояние гонки при статической инициализации. Если я могу приостановить или избежать создания потока, пока все остальные статические инициализации не будут завершены, это должно решить проблему (простой Sleep (5000) позволяет избежать проблемы, хотя это не совсем надежное решение).
Я мог бы явно вызвать функцию инициализации в нашей функции main (), однако это не идеально, так как у нас есть более 20 двоичных файлов, которые используют эту библиотеку, поэтому каждый программист должен был бы помнить, что нужно запускать инициализацию в каждом двоичном файле. Я бы предпочел передать эту ответственность компилятору, если это возможно.
Комментарий Refugnic Eternium выше верен и предлагает одно решение.
Лучшее решение — иметь такую функцию:
BOOL InitMyLib();
Все функции в MyLib.dll, и все конструкторы, должны завершиться неудачей, пока это не будет вызвано. Таким образом, вы можете быть уверены, что программисты не забудут это назвать.
Создайте класс инициализатора и затем объявите его статический экземпляр:
class MyInitializer
{
public:
MyInitializer ()
{
doInitStuffHere();
}
};
static MyInitializer myInit;
Вы можете контролировать когда статическая переменная инициализируется с помощью #pragma init_seg
, Например, #pragma init_seg (lib).
Используйте #pragma init_seg для управления статическим построением (KB104248)