По первому запросу объект создается, при разрушении статики — удаляется. Все хорошо.
Но иногда возникает ситуация, при которой происходят попытки обратиться к этому синглтону уже в процессе разрушения статики, и, иногда, уже после того, как переменная s_singleton разрушена.
Что делать? Я готов даже создавать новый экземпляр на куче или возвращать nullptr (допустим, функция возвращает указатель), но как надёжно определить тот факт, что статическая переменная уже разрушена? Можно поставить какой-то guard, который будет при разрушении ставить какую-то статическую переменную в особое состояние, но где гарантия, что дебагер, разрушая эту переменную, не затрёт её каким-то 0xDEADBEEF?
Re: Продлить жизнь статической переменной в функции
Здравствуйте, Went, Вы писали:
W>Что делать? Я готов даже создавать новый экземпляр на куче или возвращать nullptr (допустим, функция возвращает указатель), но как надёжно определить тот факт, что статическая переменная уже разрушена? Можно поставить какой-то guard, который будет при разрушении ставить какую-то статическую переменную в особое состояние, но где гарантия, что дебагер, разрушая эту переменную, не затрёт её каким-то 0xDEADBEEF?
как предположение, можно этой какой-то переменной сделать указатель на Singleton и инициализировать адресом s_singleton
если дебагер перетрет значение, то оно будет отличаться от адреса s_singleton
Re: Продлить жизнь статической переменной в функции
Здравствуйте, Went, Вы писали:
W>Есть функция — геттер синглтона: W>По первому запросу объект создается, при разрушении статики — удаляется. Все хорошо. W>Но иногда возникает ситуация, при которой происходят попытки обратиться к этому синглтону уже в процессе разрушения статики, и, иногда, уже после того, как переменная s_singleton разрушена.
W>Что делать?
Надо переходить на ручное управление.
Вместо статической локальной использовать переменную, к которой будут иметь доступ две функции: get_singleton() и destroy_singleton().
Конструировать её при первом обращении, как и раньше ( std::call_once() тебе в помощь).
А прибивать вручную, в правильном порядке, чтобы никто гарантированно не обратился к дохлой переменной.
_____________________
С уважением,
Stanislav V. Zudin
Re: Продлить жизнь статической переменной в функции
Здравствуйте, Went, Вы писали:
W>Здравствуйте. Хочется странного. W>Но иногда возникает ситуация, при которой происходят попытки обратиться к этому синглтону уже в процессе разрушения статики, и, иногда, уже после того, как переменная s_singleton разрушена.
а как такая ситуация может возникнуть? Вы же уже из main вышли. Может не делать потоки detach и ждать их завершения до завершения main?
Re[2]: Продлить жизнь статической переменной в функции
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Надо переходить на ручное управление. SVZ>Вместо статической локальной использовать переменную, к которой будут иметь доступ две функции: get_singleton() и destroy_singleton(). SVZ>Конструировать её при первом обращении, как и раньше ( std::call_once() тебе в помощь). SVZ>А прибивать вручную, в правильном порядке, чтобы никто гарантированно не обратился к дохлой переменной.
Ну, как говорится, "мопед не мой", и я не могу определить этот порядок. Я знаю только то, что "в любой момент при разрушении статики кто-то в своём деструкторе может решить обратиться к этому синглтону". Я мог бы создать этот синглтон на куче и считать ссылки, но, опять же, я не имею возможности расставить инкремент и декремент ссылок так, чтобы гарантированно после последнего декремента никто не решил снова обратиться к этому объекту.
Re[2]: Продлить жизнь статической переменной в функции
Здравствуйте, sergii.p, Вы писали: SP>а как такая ситуация может возникнуть? Вы же уже из main вышли. Может не делать потоки detach и ждать их завершения до завершения main?
Например, какой-то объект на статике в своём деструкторе решил записать что-то в лог (у меня не лог, но это не важно). То, что так делать не стоит — это другой вопрос, но для меня это данность.
Re[2]: Продлить жизнь статической переменной в функции
Здравствуйте, night beast, Вы писали: NB>как предположение, можно этой какой-то переменной сделать указатель на Singleton и инициализировать адресом s_singleton NB>если дебагер перетрет значение, то оно будет отличаться от адреса s_singleton
Разе мы тут не имеем тот же риск, что и с любым другим "особым" значением? Чем адрес синглтона принципиально отличается от любого другого magic word-а?
Re: Продлить жизнь статической переменной в функции
ИМХО, стоит подумать, как избежать обращения к статической переменной во время ее уничтожения. Сам по себе этот факт — тревожный звоночек, что что-то не так. И даже если вы сейчас решите свою проблему, потом могут вылезти другие.
Патриот здравого смысла
Re[3]: Продлить жизнь статической переменной в функции
Здравствуйте, Went, Вы писали:
SVZ>>А прибивать вручную, в правильном порядке, чтобы никто гарантированно не обратился к дохлой переменной. W>Ну, как говорится, "мопед не мой", и я не могу определить этот порядок. Я знаю только то, что "в любой момент при разрушении статики кто-то в своём деструкторе может решить обратиться к этому синглтону". Я мог бы создать этот синглтон на куче и считать ссылки, но, опять же, я не имею возможности расставить инкремент и декремент ссылок так, чтобы гарантированно после последнего декремента никто не решил снова обратиться к этому объекту.
Нууу... Если тебе нет необходимости освобождать какие-то ресурсы (т.е. обойтись без вызова деструктора), то ты можешь создавать свой синглетон не статиком, а в куче.
Тогда утечка памяти при закрытии приложения будет намеренной и неопасной, а синглетон точно переживёт всех.
_____________________
С уважением,
Stanislav V. Zudin
Re[3]: Продлить жизнь статической переменной в функции
Здравствуйте, Went, Вы писали:
SP>>а как такая ситуация может возникнуть? Вы же уже из main вышли. Может не делать потоки detach и ждать их завершения до завершения main? W>Например, какой-то объект на статике в своём деструкторе решил записать что-то в лог (у меня не лог, но это не важно). То, что так делать не стоит — это другой вопрос, но для меня это данность.
Так ли важно, чтобы у объекта-синглетона вызывался деструктор?
Если не важно, то можно в функции-геттере синглетона однократно создавать объект в куче и никогда не удалять его. Да, память не будет освобождаться, но т.к. она все равно будет подчищена при завершении программы, то не все ли равно?
Re[3]: Продлить жизнь статической переменной в функции
Здравствуйте, Went, Вы писали:
NB>>как предположение, можно этой какой-то переменной сделать указатель на Singleton и инициализировать адресом s_singleton NB>>если дебагер перетрет значение, то оно будет отличаться от адреса s_singleton W>Разе мы тут не имеем тот же риск, что и с любым другим "особым" значением? Чем адрес синглтона принципиально отличается от любого другого magic word-а?
я думаю что он не должен измениться при разрушении статики.
какое-нибудь константное инт тоже по идее не должно.
Re: Продлить жизнь статической переменной в функции
Здравствуйте, Stanislav V. Zudin, Вы писали: SVZ>Нууу... Если тебе нет необходимости освобождать какие-то ресурсы (т.е. обойтись без вызова деструктора), то ты можешь создавать свой синглетон не статиком, а в куче. SVZ>Тогда утечка памяти при закрытии приложения будет намеренной и неопасной, а синглетон точно переживёт всех.
Да, но есть момент. Синглтон thread_local, и при создании кучи тредов мы получим прогрессирующую утечку
Re[4]: Продлить жизнь статической переменной в функции
Здравствуйте, so5team, Вы писали: S>Так ли важно, чтобы у объекта-синглетона вызывался деструктор? S>Если не важно, то можно в функции-геттере синглетона однократно создавать объект в куче и никогда не удалять его. Да, память не будет освобождаться, но т.к. она все равно будет подчищена при завершении программы, то не все ли равно?
Синглтон thread_local и может весить очень много. При создании и удалении тредов можно получить прогрессирующую утечку.
Re[5]: Продлить жизнь статической переменной в функции
Здравствуйте, Went, Вы писали:
S>>Если не важно, то можно в функции-геттере синглетона однократно создавать объект в куче и никогда не удалять его. Да, память не будет освобождаться, но т.к. она все равно будет подчищена при завершении программы, то не все ли равно? W>Синглтон thread_local и может весить очень много. При создании и удалении тредов можно получить прогрессирующую утечку.
А что, при завершении работы треда вызываются деструкторы статических объектов? Или у вас разрушаются thread_local объекты и обращение к вашему thread_local синглетону происходит из деструкторов именно этих объектов?
Re[2]: Продлить жизнь статической переменной в функции
Здравствуйте, so5team, Вы писали: S>Счетчик Шварца еще не советовали?
Я о таком думал. Но есть ли гарантия, что при разрушении статики, система, работая в дебажной конфигурации, разрушая nifty_counter, не решит его забить каким-то мусором до того, как разрушится последний StreamInitializer? Или это касается только кучи?
Re[6]: Продлить жизнь статической переменной в функции
Здравствуйте, so5team, Вы писали:
S>А что, при завершении работы треда вызываются деструкторы статических объектов?
А разве при завершении треда thread_local объекты не разрушаются?
S>Или у вас разрушаются thread_local объекты и обращение к вашему thread_local синглетону происходит из деструкторов именно этих объектов?
Да, такое очень даже возможно.
Re[7]: Продлить жизнь статической переменной в функции
Здравствуйте, Went, Вы писали:
S>>А что, при завершении работы треда вызываются деструкторы статических объектов? W>А разве при завершении треда thread_local объекты не разрушаются?
Так вы бы внесли ясность в тему: у вас thread_local или static объекты (или даже static thread_local). Потому что именно static объекты создаются при начале работы программы (до main) и разрушаются после выхода из main. Отдельная тема со static внутри функций, тут создание происходит при первом обращении к этой функции (или даже при первом входе в scope, в котором локальный static объект объявляется), но разрушаются такие объекты все равно после выхода из main. К тредам эти статические объекты, насколько я помню, отношения не имеют. Создание/разрушение тредов на них не сказывается.
Здравствуйте, Went, Вы писали:
SVZ>>Нууу... Если тебе нет необходимости освобождать какие-то ресурсы (т.е. обойтись без вызова деструктора), то ты можешь создавать свой синглетон не статиком, а в куче. SVZ>>Тогда утечка памяти при закрытии приложения будет намеренной и неопасной, а синглетон точно переживёт всех. W>Да, но есть момент. Синглтон thread_local, и при создании кучи тредов мы получим прогрессирующую утечку
Тогда вероятно стоит делать закат солнца вручную ручное распараллеливание синглетона на потоки.
Глобальный синглетон, внутри хеш с обработчиками (что у тебя этот синглетон должен делать), в качестве ключа std::thread::id.
А в thread_local — (де-)регистрация обработчиков, чтобы хеш чистился при завершении потоков.
Если поток по ключу не найден, то запрос обрабатывает специальный обработчик "для потеряшек".
Ну вот так как-то.
_____________________
С уважением,
Stanislav V. Zudin