Продлить жизнь статической переменной в функции
От: Went  
Дата: 07.09.22 07:07
Оценка:
Здравствуйте. Хочется странного.
Есть функция — геттер синглтона:
Singleton& get_singleton()
{
  static Singleton s_singleton;
  return s_singleton;
}

По первому запросу объект создается, при разрушении статики — удаляется. Все хорошо.
Но иногда возникает ситуация, при которой происходят попытки обратиться к этому синглтону уже в процессе разрушения статики, и, иногда, уже после того, как переменная s_singleton разрушена.
Что делать? Я готов даже создавать новый экземпляр на куче или возвращать nullptr (допустим, функция возвращает указатель), но как надёжно определить тот факт, что статическая переменная уже разрушена? Можно поставить какой-то guard, который будет при разрушении ставить какую-то статическую переменную в особое состояние, но где гарантия, что дебагер, разрушая эту переменную, не затрёт её каким-то 0xDEADBEEF?
Re: Продлить жизнь статической переменной в функции
От: night beast СССР  
Дата: 07.09.22 07:19
Оценка:
Здравствуйте, Went, Вы писали:

W>Что делать? Я готов даже создавать новый экземпляр на куче или возвращать nullptr (допустим, функция возвращает указатель), но как надёжно определить тот факт, что статическая переменная уже разрушена? Можно поставить какой-то guard, который будет при разрушении ставить какую-то статическую переменную в особое состояние, но где гарантия, что дебагер, разрушая эту переменную, не затрёт её каким-то 0xDEADBEEF?


как предположение, можно этой какой-то переменной сделать указатель на Singleton и инициализировать адресом s_singleton
если дебагер перетрет значение, то оно будет отличаться от адреса s_singleton
Re: Продлить жизнь статической переменной в функции
От: · Великобритания  
Дата: 07.09.22 07:42
Оценка: +3 -1
Здравствуйте, Went, Вы писали:

W> Что делать?

Не использовать синглтоны и глобальные переменные.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Продлить жизнь статической переменной в функции
От: Stanislav V. Zudin Россия  
Дата: 07.09.22 07:46
Оценка:
Здравствуйте, Went, Вы писали:

W>Есть функция — геттер синглтона:

W>По первому запросу объект создается, при разрушении статики — удаляется. Все хорошо.
W>Но иногда возникает ситуация, при которой происходят попытки обратиться к этому синглтону уже в процессе разрушения статики, и, иногда, уже после того, как переменная s_singleton разрушена.

W>Что делать?


Надо переходить на ручное управление.
Вместо статической локальной использовать переменную, к которой будут иметь доступ две функции: get_singleton() и destroy_singleton().
Конструировать её при первом обращении, как и раньше ( std::call_once() тебе в помощь).
А прибивать вручную, в правильном порядке, чтобы никто гарантированно не обратился к дохлой переменной.
_____________________
С уважением,
Stanislav V. Zudin
Re: Продлить жизнь статической переменной в функции
От: sergii.p  
Дата: 07.09.22 07:56
Оценка:
Здравствуйте, Went, Вы писали:

W>Здравствуйте. Хочется странного.

W>Но иногда возникает ситуация, при которой происходят попытки обратиться к этому синглтону уже в процессе разрушения статики, и, иногда, уже после того, как переменная s_singleton разрушена.

а как такая ситуация может возникнуть? Вы же уже из main вышли. Может не делать потоки detach и ждать их завершения до завершения main?
Re[2]: Продлить жизнь статической переменной в функции
От: Went  
Дата: 07.09.22 08:04
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Надо переходить на ручное управление.

SVZ>Вместо статической локальной использовать переменную, к которой будут иметь доступ две функции: get_singleton() и destroy_singleton().
SVZ>Конструировать её при первом обращении, как и раньше ( std::call_once() тебе в помощь).
SVZ>А прибивать вручную, в правильном порядке, чтобы никто гарантированно не обратился к дохлой переменной.
Ну, как говорится, "мопед не мой", и я не могу определить этот порядок. Я знаю только то, что "в любой момент при разрушении статики кто-то в своём деструкторе может решить обратиться к этому синглтону". Я мог бы создать этот синглтон на куче и считать ссылки, но, опять же, я не имею возможности расставить инкремент и декремент ссылок так, чтобы гарантированно после последнего декремента никто не решил снова обратиться к этому объекту.
Re[2]: Продлить жизнь статической переменной в функции
От: Went  
Дата: 07.09.22 08:06
Оценка:
Здравствуйте, sergii.p, Вы писали:
SP>а как такая ситуация может возникнуть? Вы же уже из main вышли. Может не делать потоки detach и ждать их завершения до завершения main?
Например, какой-то объект на статике в своём деструкторе решил записать что-то в лог (у меня не лог, но это не важно). То, что так делать не стоит — это другой вопрос, но для меня это данность.
Re[2]: Продлить жизнь статической переменной в функции
От: Went  
Дата: 07.09.22 08:10
Оценка:
Здравствуйте, night beast, Вы писали:
NB>как предположение, можно этой какой-то переменной сделать указатель на Singleton и инициализировать адресом s_singleton
NB>если дебагер перетрет значение, то оно будет отличаться от адреса s_singleton
Разе мы тут не имеем тот же риск, что и с любым другим "особым" значением? Чем адрес синглтона принципиально отличается от любого другого magic word-а?
Re: Продлить жизнь статической переменной в функции
От: DiPaolo Россия  
Дата: 07.09.22 08:10
Оценка:
ИМХО, стоит подумать, как избежать обращения к статической переменной во время ее уничтожения. Сам по себе этот факт — тревожный звоночек, что что-то не так. И даже если вы сейчас решите свою проблему, потом могут вылезти другие.
Патриот здравого смысла
Re[3]: Продлить жизнь статической переменной в функции
От: Stanislav V. Zudin Россия  
Дата: 07.09.22 08:11
Оценка:
Здравствуйте, Went, Вы писали:

SVZ>>А прибивать вручную, в правильном порядке, чтобы никто гарантированно не обратился к дохлой переменной.

W>Ну, как говорится, "мопед не мой", и я не могу определить этот порядок. Я знаю только то, что "в любой момент при разрушении статики кто-то в своём деструкторе может решить обратиться к этому синглтону". Я мог бы создать этот синглтон на куче и считать ссылки, но, опять же, я не имею возможности расставить инкремент и декремент ссылок так, чтобы гарантированно после последнего декремента никто не решил снова обратиться к этому объекту.

Нууу... Если тебе нет необходимости освобождать какие-то ресурсы (т.е. обойтись без вызова деструктора), то ты можешь создавать свой синглетон не статиком, а в куче.
Тогда утечка памяти при закрытии приложения будет намеренной и неопасной, а синглетон точно переживёт всех.
_____________________
С уважением,
Stanislav V. Zudin
Re[3]: Продлить жизнь статической переменной в функции
От: so5team https://stiffstream.com
Дата: 07.09.22 08:13
Оценка: +5
Здравствуйте, Went, Вы писали:

SP>>а как такая ситуация может возникнуть? Вы же уже из main вышли. Может не делать потоки detach и ждать их завершения до завершения main?

W>Например, какой-то объект на статике в своём деструкторе решил записать что-то в лог (у меня не лог, но это не важно). То, что так делать не стоит — это другой вопрос, но для меня это данность.

Так ли важно, чтобы у объекта-синглетона вызывался деструктор?

Если не важно, то можно в функции-геттере синглетона однократно создавать объект в куче и никогда не удалять его. Да, память не будет освобождаться, но т.к. она все равно будет подчищена при завершении программы, то не все ли равно?
Re[3]: Продлить жизнь статической переменной в функции
От: night beast СССР  
Дата: 07.09.22 08:16
Оценка:
Здравствуйте, Went, Вы писали:

NB>>как предположение, можно этой какой-то переменной сделать указатель на Singleton и инициализировать адресом s_singleton

NB>>если дебагер перетрет значение, то оно будет отличаться от адреса s_singleton
W>Разе мы тут не имеем тот же риск, что и с любым другим "особым" значением? Чем адрес синглтона принципиально отличается от любого другого magic word-а?

я думаю что он не должен измениться при разрушении статики.
какое-нибудь константное инт тоже по идее не должно.
Re: Продлить жизнь статической переменной в функции
От: so5team https://stiffstream.com
Дата: 07.09.22 08:24
Оценка: 36 (6)
Здравствуйте, Went, Вы писали:

W>Что делать?


Счетчик Шварца еще не советовали?
Re[4]: Продлить жизнь статической переменной в функции
От: Went  
Дата: 07.09.22 08:33
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Нууу... Если тебе нет необходимости освобождать какие-то ресурсы (т.е. обойтись без вызова деструктора), то ты можешь создавать свой синглетон не статиком, а в куче.
SVZ>Тогда утечка памяти при закрытии приложения будет намеренной и неопасной, а синглетон точно переживёт всех.
Да, но есть момент. Синглтон thread_local, и при создании кучи тредов мы получим прогрессирующую утечку
Re[4]: Продлить жизнь статической переменной в функции
От: Went  
Дата: 07.09.22 08:35
Оценка:
Здравствуйте, so5team, Вы писали:
S>Так ли важно, чтобы у объекта-синглетона вызывался деструктор?
S>Если не важно, то можно в функции-геттере синглетона однократно создавать объект в куче и никогда не удалять его. Да, память не будет освобождаться, но т.к. она все равно будет подчищена при завершении программы, то не все ли равно?
Синглтон thread_local и может весить очень много. При создании и удалении тредов можно получить прогрессирующую утечку.
Re[5]: Продлить жизнь статической переменной в функции
От: so5team https://stiffstream.com
Дата: 07.09.22 08:42
Оценка:
Здравствуйте, Went, Вы писали:

S>>Если не важно, то можно в функции-геттере синглетона однократно создавать объект в куче и никогда не удалять его. Да, память не будет освобождаться, но т.к. она все равно будет подчищена при завершении программы, то не все ли равно?

W>Синглтон thread_local и может весить очень много. При создании и удалении тредов можно получить прогрессирующую утечку.

А что, при завершении работы треда вызываются деструкторы статических объектов? Или у вас разрушаются thread_local объекты и обращение к вашему thread_local синглетону происходит из деструкторов именно этих объектов?
Re[2]: Продлить жизнь статической переменной в функции
От: Went  
Дата: 07.09.22 08:45
Оценка:
Здравствуйте, so5team, Вы писали:
S>Счетчик Шварца еще не советовали?
Я о таком думал. Но есть ли гарантия, что при разрушении статики, система, работая в дебажной конфигурации, разрушая nifty_counter, не решит его забить каким-то мусором до того, как разрушится последний StreamInitializer? Или это касается только кучи?
Re[6]: Продлить жизнь статической переменной в функции
От: Went  
Дата: 07.09.22 08:48
Оценка:
Здравствуйте, so5team, Вы писали:

S>А что, при завершении работы треда вызываются деструкторы статических объектов?

А разве при завершении треда thread_local объекты не разрушаются?

S>Или у вас разрушаются thread_local объекты и обращение к вашему thread_local синглетону происходит из деструкторов именно этих объектов?

Да, такое очень даже возможно.
Re[7]: Продлить жизнь статической переменной в функции
От: so5team https://stiffstream.com
Дата: 07.09.22 09:00
Оценка: +2
Здравствуйте, Went, Вы писали:

S>>А что, при завершении работы треда вызываются деструкторы статических объектов?

W>А разве при завершении треда thread_local объекты не разрушаются?

Так вы бы внесли ясность в тему: у вас thread_local или static объекты (или даже static thread_local). Потому что именно static объекты создаются при начале работы программы (до main) и разрушаются после выхода из main. Отдельная тема со static внутри функций, тут создание происходит при первом обращении к этой функции (или даже при первом входе в scope, в котором локальный static объект объявляется), но разрушаются такие объекты все равно после выхода из main. К тредам эти статические объекты, насколько я помню, отношения не имеют. Создание/разрушение тредов на них не сказывается.

https://wandbox.org/permlink/kLeo5BCuDX3l1z3X
Re[5]: Продлить жизнь статической переменной в функции
От: Stanislav V. Zudin Россия  
Дата: 07.09.22 09:07
Оценка: 4 (1)
Здравствуйте, Went, Вы писали:

SVZ>>Нууу... Если тебе нет необходимости освобождать какие-то ресурсы (т.е. обойтись без вызова деструктора), то ты можешь создавать свой синглетон не статиком, а в куче.

SVZ>>Тогда утечка памяти при закрытии приложения будет намеренной и неопасной, а синглетон точно переживёт всех.
W>Да, но есть момент. Синглтон thread_local, и при создании кучи тредов мы получим прогрессирующую утечку

Тогда вероятно стоит делать закат солнца вручную ручное распараллеливание синглетона на потоки.
Глобальный синглетон, внутри хеш с обработчиками (что у тебя этот синглетон должен делать), в качестве ключа std::thread::id.

А в thread_local — (де-)регистрация обработчиков, чтобы хеш чистился при завершении потоков.
Если поток по ключу не найден, то запрос обрабатывает специальный обработчик "для потеряшек".

Ну вот так как-то.
_____________________
С уважением,
Stanislav V. Zudin
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.