Зависший и не отвечающий поток разумеется к случаям не относится, да. А программы у нас все пишут просто идеально.CleverMouse wrote:Не прибивать дочерний поток. Насильственное прибивание потока - вообще настолько странная операция, что я не могу назвать ни одного случая, когда она действительно нужна.
Помогите новичку
-
Всем чмоки в этом проекте! Засуньте эти 11 лет себе в жопу!
Неотвечающий поток чем-то занят. Конечно, он может крутиться в бесполезном бесконечном цикле, но могут быть и другие варианты. Например, поток занят сбросом на диск всего, что записала функция файловой системы. В этом случае убивать его чревато.
В том же Linux есть зомби. Пока в Колибри нет механизмов, позволяющих отсрочить смерть, - убивать потоки, занятые непонятно чем, просто нельзя.
В том же Linux есть зомби. Пока в Колибри нет механизмов, позволяющих отсрочить смерть, - убивать потоки, занятые непонятно чем, просто нельзя.
Сделаем мир лучше!
Тогда нужно вводить какой-то дополнительный признак который сообщит, взаимодействует поток с ядром или живет богатым внутренним миром, выполняя условно-бесконечный цикл.CleverMouse wrote:Неотвечающий поток чем-то занят. Конечно, он может крутиться в бесполезном бесконечном цикле, но могут быть и другие варианты. Например, поток занят сбросом на диск всего, что записала функция файловой системы. В этом случае убивать его чревато.
В том же Linux есть зомби. Пока в Колибри нет механизмов, позволяющих отсрочить смерть, - убивать потоки, занятые непонятно чем, просто нельзя.
Всем чмоки в этом проекте! Засуньте эти 11 лет себе в жопу!
Я закоммитила r3296 и r3303-r3304, теперь ядро гарантированно не упадёт вслед за убитым потоком. Но это не даёт права убивать потоки, занятые неизвестно чем, по той же причине: поток может быть в середине важной операции, прерывание которой может закончиться плачевно. Например, поток мог копировать файл, тогда в итоге будет скопирован только кусок файла. Или поток мог сохранять настройки в уже существующий ini-файл, вставляя куда-нибудь посередине новую строку, тогда в ini-файле будет каша из старого и нового, что наверняка очень удивит программу при следующем запуске. Ещё раз: нельзя убивать потоки, нужно договариваться с ними о смерти.
Сделаем мир лучше!
Объясните, что означают эти ошибки:
- Attachments
-
-
1.PNG (6.76 KiB)Viewed 5357 times
-
Главное тут EIP - он силишком большой, так что судя по всему выход за границу памяти.
Из хаоса в космос
Или это падение в ядре, что более вероятно.
Главное тут действительно EIP. В диапазоне адресов с 80010000 до примерно 80040000 располагается ядро. При разработке приложений падение в районе ядра практически всегда означает вызов системной функции с неверными параметрами.
В последней русской ночной сборке по адресам 800226E9 и 8001AD88 ничего интересного нет; в последней английской ночной сборке 800226E9 = file_system_lfn+0Ah, 8001AD88 = dtext.text_asciiz, так что неверные параметры в функциях 70 и 4 соответственно. Адреса всех меток ядра можно узнать, скомпилировав ядро с отладочной информацией - галочка в Колибри-версии, ключ -s с утилитой symbols в остальных версиях.
В последней русской ночной сборке по адресам 800226E9 и 8001AD88 ничего интересного нет; в последней английской ночной сборке 800226E9 = file_system_lfn+0Ah, 8001AD88 = dtext.text_asciiz, так что неверные параметры в функциях 70 и 4 соответственно. Адреса всех меток ядра можно узнать, скомпилировав ядро с отладочной информацией - галочка в Колибри-версии, ключ -s с утилитой symbols в остальных версиях.
Сделаем мир лучше!
CleverMouse, спасибо.
Да, это как раз было в английской сборке svn3306.
Такое у меня бывает не очень часто, главный поток при этом продолжает работать.
А дочерний я убиваю из главного с помощью 18.18.
Вот тут viewtopic.php?p=39992#p39992 я приводил скриншот этой программы. Перед появлением нового подменю поток старого убивается 18.18. Тогда это мне показалось удобным. Если причина ошибок в этом, то как можно было по-другому сделать? IPC?
Да, это как раз было в английской сборке svn3306.
Такое у меня бывает не очень часто, главный поток при этом продолжает работать.
А дочерний я убиваю из главного с помощью 18.18.
Вот тут viewtopic.php?p=39992#p39992 я приводил скриншот этой программы. Перед появлением нового подменю поток старого убивается 18.18. Тогда это мне показалось удобным. Если причина ошибок в этом, то как можно было по-другому сделать? IPC?
Для GUI-потоков проще всего делать так:
* в том потоке, который нужно уметь завершать: назначать идентификаторы всех кнопок, если они вообще есть, от 2 и выше,
* в цикле выборки сообщений того же потока: если приходит событие о нажатии кнопки и кнопка имеет идентификатор 1, поток завершает работу;
* в главном потоке, который хочет завершить предыдущий поток: вызвать функцию 72 с параметрами "нажать кнопку с идентификатором 1".
Саму кнопку с идентификатором 1 создавать не нужно.
Но на причину конкретно этих падений убивание функцией 18.18 не тянет.
* в том потоке, который нужно уметь завершать: назначать идентификаторы всех кнопок, если они вообще есть, от 2 и выше,
* в цикле выборки сообщений того же потока: если приходит событие о нажатии кнопки и кнопка имеет идентификатор 1, поток завершает работу;
* в главном потоке, который хочет завершить предыдущий поток: вызвать функцию 72 с параметрами "нажать кнопку с идентификатором 1".
Саму кнопку с идентификатором 1 создавать не нужно.
Но на причину конкретно этих падений убивание функцией 18.18 не тянет.
Сделаем мир лучше!
Попробовал сделать как ты сказала — работает. И вроде бы даже нашёл, в чём была ошибка: раньше я не ждал пока поток завершится и запускал новый поток. На главный поток это не влияло, но у этих двух был общий стек(да и не только стек). Однако, вот тут viewtopic.php?p=39994#p39994 Serge писал, что завершаемый поток не получит управления. Но всё-таки те ошибки теперь почему-то не появляются.
Тогда это было верно. Сейчас — нет.
Сделаем мир лучше!
Если предыдущий не успел нарисовать окно, то закрываются чужие окна.* в главном потоке, который хочет завершить предыдущий поток: вызвать функцию 72 с параметрами "нажать кнопку с идентификатором 1".
В версии с 18.18 иногда дочерний поток виснет и его невозможно убить через CPU.
У меня запуск/завершение потоков происходит при движении мыши, и, если делать это быстро-быстро, то возникают глюки.
0CodErr
Заведи глобальную переменную на каждый поток и передавай через неё команды потокам.
Например
Заведи глобальную переменную на каждый поток и передавай через неё команды потокам.
Например
Code: Select all
volatile int thread_action;
Поток a закрывает поток b
thread_action = CLOSE;
while( thread_action != DONE )
delay(xxx);
поток b
while(thread_action != CLOSE)
{
основной цикл потока
}
thread_action = DONE;
exit_thread();