- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
// We now have a locale string, but the global locale can be changed by
// another thread. If we allow this thread's locale to be updated before we're done
// with this string, it might be freed from under us.
// Call versions of the wide-to-MB-char conversions that do not update the current thread's
// locale.
//...
/*
* Note that we are using a risky trick here. We are adding this
* locale to an existing threadlocinfo struct, and thus starting
* the locale's refcount with the same value as the whole struct.
* That means all code which modifies both threadlocinfo::refcount
* and threadlocinfo::lc_category[]::refcount in structs that are
* potentially shared across threads must make those modifications
* under _SETLOCALE_LOCK. Otherwise, there's a race condition
* for some other thread modifying threadlocinfo::refcount after
* we load it but before we store it to refcount.
*/
LispGovno 23.01.2015 19:50 # 0
guest 23.01.2015 19:50 # 0
LispGovno 23.01.2015 19:55 # 0
guest 23.01.2015 20:00 # 0
LispGovno 23.01.2015 22:54 # 0
Ты лучше прочитай что написано в нульпосте и наматывай на ус. Это из кода setlocale
guest 24.01.2015 17:27 # 0
bormand 23.01.2015 20:32 # +3
LispGovno 23.01.2015 22:56 # 0
bormand 23.01.2015 23:05 # 0
LispGovno 23.01.2015 23:07 # 0
bormand 23.01.2015 20:35 # +2
Dummy00001 23.01.2015 21:49 # +1
на большинстве юнихов та же песня.
на одном проекте реально из С вызывали жабу - только для того что бы Сшную локаль не трогать.
bormand 23.01.2015 21:52 # +1
Ну и таймзоны. Каким мудаком надо быть, чтобы сделать gmtime()+localtime(), но в обратную сторону замутить только один mktime() - х.з. Причем ни одна из этих функций не позволяет настраивать таймзону кроме как через окружение.
P.S. В timegm() еще ман стёбный: предлагает не юзать его, а заменить на говно с установкой TZ=UTC и вызовом mktime (можно смело выкладывать на ГК).
bormand 23.01.2015 22:01 # 0
Soul_re@ver 23.01.2015 22:50 # 0
Я джвадцать лет жду возможности нормально завершить программу из любого места кроме как выбрасыванием исключения и ловли его в main()
LispGovno 23.01.2015 22:52 # 0
Soul_re@ver 24.01.2015 01:16 # 0
У std::exit есть очень серьёзный недостаток: она не раскручивает стек. В сишке всем похуй, так как деструкторов нет, а в крестах это проблема ибо RAII.
Остальные способы быстро выйти чистят ещё меньше. Вот и приходится кидать какой-нибудь exit_exception или возвращать определённое значение, проверять его в вызывающей функции, возвращать... пока не доберёшся до мэйна
LispGovno 24.01.2015 11:27 # 0
Dummy00001 25.01.2015 13:17 # +1
Пости примеры сюда. Мы посмеемся. Потому что это 100% навярняка говно.
Это верный знак кривой логики программы - или кривых рук программиста.
ЗЫ Бросание и ловление в мэйне уникального исключения. Это то как этот хак делается в крестах.
Soul_re@ver 25.01.2015 20:43 # 0
Кнопка — выход. Делать ничего руками не нужно, RAII приберёт. Да, сейчас бросается исключение (не унаследованное ни от чего, чтобы случайно не ловилось) и ловится в мэйне.
Почему не дать exit ожидаемого поведения, мне непонятно. Для немедленного завершения программы без уборки есть quick_exit, abort, etc
bormand 25.01.2015 20:53 # +2
Soul_re@ver 25.01.2015 23:52 # 0
Ни особых преимуществ, кроме централизованной обработки, ни недостатков, кроме большего объёма кода.
Просто у меня бомбит, что существует 4 минимально отличающиеся функции для аварийного завершения работы и ни одной для нормального.
Dummy00001 26.01.2015 00:11 # +1
Э??
Это же стандартный книжный способ?
> существует 4 минимально отличающиеся функции для аварийного завершения работы
четыре? это какие именно? в позиксе/ц стандарте я помню только три: exit(), _exit() и abort(). и они очень сильно друг от друга отличаются.
bormand 26.01.2015 12:10 # 0
Да вроде бы вообще все(?) event loop'ы так построены. Ну с поправкой на то, как это сообщение отправляется: где-то именно сообщением (например winapi), где-то вызовом метода stop() или quit() у лупа (например boost::asio, qt)
roman-kashitsyn 26.01.2015 12:42 # 0
там ещё есть мега-способ с объектом work, который мешает циклу выйти.
bormand 26.01.2015 14:10 # 0
Dummy00001 25.01.2015 22:57 # 0
Потому что это в общем случае не возможно.
Простейший примеры: exit() из глубин конструктора; exit() в одном потоке и развертка стеков в других потоках.
По тому что у тебя есть проблема с выходом, можно также догадатся что у тебя есть и проблемы с инициализацией: порядком и пунктом времени когда объекты создаются.
Если у тебя это проблемы, то пользуйся синглтонами + спец функция выхода которая все синглтоны удаляет перед сисколом выхода.
Soul_re@ver 26.01.2015 00:00 # 0
А в чём проблема? Как аварийное завершение конструктора: объект не считается созданным (хоть это и не важно, т.к использовать его некому), память возвращается обратно.
>exit() в одном потоке и развертка стеков в других потоках.
В общем случае exit() в многопоточном приложении ЕМНИП вызывает UB и сейчас, если текущий поток завершается до того как завершатся дочерние потоки.
Проблем с инициализацией нет, как и нет их с выходом, если деструкторы отработают. Вариант с исключением работает нормально, вариант предложенный bormandом тоже бы работал прекрасно.
Просто, как я отписал выше, иметь несколько почти не отличающихся функций для аварийного выхода и ни одной для нормального.
Dummy00001 26.01.2015 00:23 # 0
причем тут память? это та же дежурная проблема объекта созданного на половину.
освобождение памяти как раз при выходе никого не интересует: процес закончится, вся память разом освободится.
> если текущий поток завершается до того как завершатся дочерние потоки.
exit() может быть вызван и в дочернем потоке.
вообщем я твоей проблемы просто не уловил. как раз в С сложнее сделать корректный выход из программы. потому что его в ручную делать надо. в С++ есть все средства, но народы строят такие кластерфаки ООП что сами потом разгрести не могут. я по старой традиции никогда ничего важного в конструкторы/деструкторы не пихаю, потому что предпочитаю иметь более тонкий контроль жизненого цикла объектов. это уже не говоря про то что как правило стараюсь всегда делать стого иерархические агрегации. если надо - несколько иерархий, но опять же с четким разганичением ответственностей этих иерархий. в последней большой крестовой программе которую, я мог бы сделать 100% корректный выход в любой точке программы вызовом друх delete'ов на глобальные объекты + exit().
Soul_re@ver 26.01.2015 11:29 # 0
И решать её так же как и в случае с исключениями: автором класса которому следует предусмотреть что случится если написанный им exit выполнится.
Вообще механика работы исключений для «стандартного» выхода подошла бы.
> exit() может быть вызван и в дочернем потоке.
И завершение работы программы до того как завершатся все потоки всё ещё UB, так что новых способов выстрелить в ногу это не приносит.
> вообщем я твоей проблемы просто не уловил.
Проблемы как таковой нет. Есть досада на отсутствие синтаксического сахара в языке и необходимость в общем случае использовать не предназначенные для этого инструменты.
Вот в стандарте есть:
exit(), (который как мне сказали по стандарту вызывается посли завершения main и поэтому его поведение не может быть изменено) вызывающий atexit функции и разрушающий статичные объекты.
quick_exit(), вызывающий обработчики at_quick_exit(), a затем _Exit
_Exit, завершающий работу программы без уборки
abort() отличающийся от _Exit только тем, что кидает сигнал.
Dummy00001 26.01.2015 12:42 # 0
а. наконец таки добрались до оригинальной проблемы.
> abort() отличающийся от _Exit только тем, что кидает сигнал.
кидает а может и не кидает. и как бы совсем не exit()
цель abort() в том что бы приложение в корку повалить програмно. дебаг фича.
exit()/quick_exit()/_exit() тоже как бы понятно. это просто хуки в разные фазы завершения программы, exit() самый верхний уровень, quick_exit() где-то по середине, и _exit() это более или менее живой syscall который в приложение никогда не возвращается.
стандартные стримы флашатся и деструкторы статических объектов вызываются exit()ом. (и atexit() хуки.)
quick_exit() ввели что бы разделить выход из программы от вызова деструкторов статических объектов.
другими словами. в общем случае тебе _exit() и quick_exit() не нужны. и abort() только для отладки. и остается только один вызов: exit().
Soul_re@ver 26.01.2015 13:13 # 0
(размотка стека и выход и мэйна)
exit(): вызов обработчиков atexit и разрушение статических объектов
_Exit(): завершение программы.
quick_exit вызываетобработчики at_quick_exit(), a затем _Exit. Стоит слегка особняком.
Нет возможности принудить к исполнению первую фазу: развернуть весь стек и вернуть какое-либо значение из основной функции: для основного потока: main, для остальных — функция треда.
Dummy00001 26.01.2015 15:36 # 0
единственное что стэк разворачивает - это в С++ бросание исключений. весь код для разворачивания генерится компилером/берется из компилерной ран-тайм либы и живет исключительно в самой программе, в юзерспэйсе.
кернелу, который "завершает" приложение, стэк и все прочее что там лежит в памяти приложения просто по барабану.
единственное что остается неупомянутым напрямую это либц. но и она как бы *С* библиотека и в С разварачивания стэка в принципе нету.
Soul_re@ver 27.01.2015 16:19 # 0
В скобках оно, потому что это забота программиста и не часть автоматического завершения.
bormand 23.01.2015 22:54 # 0
А ведь в питоне так и делают...
LispGovno 23.01.2015 22:58 # 0
Dummy00001 23.01.2015 22:58 # 0
с локалями и таймзонами есть еще одна неожиданная проблемка портабельности: имена локалей и таймзонов ни фига не стандартизированы. на проекте пару лет назад на это дело нарвались - Solaris vs Linux - трахались месяца три: в каком месте, какое название для какой локали/таймзоны задавать. главные грабли были что сложно придти и сказать кастомеру "плиз ребутни все 20 серваков - нам надо новые конфиги проверить."
LispGovno 23.01.2015 23:00 # 0
bormand 23.01.2015 23:06 # 0
LispGovno 23.01.2015 23:09 # 0
Dummy00001 23.01.2015 23:11 # 0
да и проблем и именами это в принципе решить не может, если конечно буст с собой не таскает свои собственные файлы определения локалей (как это делает жаба).
bormand 23.01.2015 23:21 # 0
Dummy00001 23.01.2015 23:24 # 0
а. тогда верю.
LispGovno 23.01.2015 23:05 # 0
А ведь кроме сетлокали нужно видимо ещё что-то вызвать, чтобы полностью контекст тредлокальной питушни сбросить?
bormand 23.01.2015 23:07 # 0
LispGovno 23.01.2015 23:08 # 0
Dummy00001 23.01.2015 23:31 # 0
guest 24.01.2015 11:31 # +2
guest 24.01.2015 11:49 # 0
LispGovno 24.01.2015 14:48 # 0