![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Насколько я знаю, для правильного функционирования CRT в потоках требуется инициализация потока при помощи _beginthread(ex) .
Т.е. дополнительно создается вот такая структура, которая хранит все глобальные переменные, которые использует CRT.
Теперь ситуация. Функция вызывается калбеком из чужого модуля (из дополнительного потока), который, не вызывал нужной _beginthread (каждый CRT, как я понимаю, требует свой _beginthread). К чему приведет в этом случае использование функций CRT? -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 1 Всего: 37 |
ИМХО если функции не используют общих объектов, то все Ок будет. Если используют (по комментам видно, что это за функции) то могут сработать некорректно конкурируя за данные или пытаясь посмотреть CRT контекст потока.
Это сообщение отредактировал(а) Sartorius - 15.11.2010, 14:33 |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Допустим что можно отказаться от явного использования указанных функций (хотя это плохое решение), но ведь их вполне может использовать стандартная библиотека STL . -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 5 Всего: 95 |
Ну, видимо, к тому, от чего призвана защитить функция _beginthreadex: всякие внутренние СRT-шные переменные типа errno,_doserrno, strtok, _wcstok, strerror и легион им подобных могут начать показывать неактуальные значения, что может привести к неуловимым глюкам, зависящим от расположения звёзд в созвездии Плеяды. -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 1 Всего: 37 |
Alexeis, а откуда ты beginthread взял этот? Используй CreateThread
Посмотри исходники CRT. Там всякие strtok-и вызывают первым делом _getpdt. ptd создает контекст потока, если его еще нет. Все будет Ок, CRT не дураки писали. ЗЫ В общем никогда не встречал проблем с вызовом CRT функций из любых потоков. Это сообщение отредактировал(а) Sartorius - 15.11.2010, 15:32 |
|||
|
||||
| Alexeis |
|
||||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
MSDN рекомендует обратное.
Проверил. Действительно, и билдер и студия создают блок переменных потока по первой необходимости. Единственная проблема, это утечка памяти. Вероятно следует вызвать _freeptd() по окончанию пользования этим потоком, иначе ведь возникнет утечка памяти. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||
|
|||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Вот что написано в MSDN по поводу CreateProcess:
|
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Насколько я понял, проблема еще в том, что любое аппаратное исключение типа AV или деление на 0 приведет к краху, поскольку SEH фрейм не будет создан. Кроме того, оказывается следует вызывать не _freeptd() , а специально созданную _endthreadex() . Добавлено через 4 минуты и 11 секунд P.S. в моей ситуации SEH фрейм создаст билдер (точнее библиотеки delphi), так что этой проблемы не будет. С другой стороны будут созданы 2е копии переменных. Одна для CRT билдера, другая для CRT студии. Билдер свою почистит, а ту что создаст студия придется очищать руками. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 1 Всего: 37 |
||||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Sartorius, цитирую рихтера
Рихтер обманывать не будет. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
в принципе, нам же ни кто не мешает правильно инициализировать поток CRT:
это код из threadex.c, _initaddr - это и есть сама процедура потока но смотреть надо конечно не _callthreadstartex, а _threadstartex, в которой и происходит инициализация переменных а приоткрыть внутренние функции CRT не так и сложно, достаточно их просто объявить -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
GremlinProg, такой код неприменим касательно в контексте CallBack вызовов. Как уже сказано выше, _getptd() и так вызывается по первому запросу. А блок __try{}__except(){} придется вставлять в каждую из функций обратного вызова, которые будут вызваны из дополнительного потока. Один такой блок можно организовать только внутри функции потока, а она физически расположена с другом модуле. Но это работать все равно не будет, и вот почему
функция _beginthread производит инициализацию SEH для каждого потока. Без этого __try{}__except(){} будет работать неправильно. Смотрим фрагмент
Выводы следующие. 1) Вызовы CRT безопасны в функциях обратного вызова вызванных из дополнительного потока, даже если поток не создавался с _beginthread(ex). 2) Вызовы CRT в случае №1 могут приводить к утечке ресурсов, что впрочем решается дополнительным вызовом _endthreadex(), который явно освобождает ресурсы . 3) Вызовы CRT в случае №1, также не могут использовать функцию signal / __try{}__except(){}, по крайней мере до тех пор пока SEH не будет инициализирован явно. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
ну конечно, в этом и смысл: завернуть работу CRT в твоем плагине в SEH со стандартным фильтром CRT: _XcptFilter, ничего криминального тут нет: хочешь CRT - оберни исключения в CRT-фильтр хочешь еще и переменные CRT - инициируй поток, как в _threadstartex, это и есть отправная точка любого CRT-потока, и не важно, что ты это сделаешь только в функции своей библиотеки SEH организует _callthreadstartex в самом потоке, я же его показал, а _beginthread производит инициализацию _ptiddata, которую подчищает _endthreadex угу, смотрим, к чему он? -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 7 Всего: 459 |
Это код аналогичный _threadstartex, но из билдера. Смутила фраза
И дальше идет код претендующий на полноту инициализации потока, хотя таковым не является. Полная инициализация потребует вызовов из _threadstartex и из _callthreadstartex. Причем, вероятно этот код будет непереносим на последующие версии студии. А это нехорошо. Лучше обойтись документированными средствами. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| GremlinProg |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
это был ответ на твою последнюю цитату, ты просто сам зачем-то разделил понятия SEH с __try-__except, хотя последнее как раз этот SEH и ставит, вот я и сделал на нем акцент, раз уж тебе важно было использовать signal
именно это я и отметил
был смысл придираться? он просто ни о чем не говорит, чтобы из него еще и выводы какие-то делать, аналогий с предыдущей установкой SEH, я по крайней мере не вижу RTL exception handler - это видимо подразумевается все таки простая функция, но не SEH (билдер не использую, точнее не скажу) -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||
|
|||||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |