Page 45 of 77

Re: Помогите новичку

Posted: Thu Feb 28, 2013 8:50 pm
by Mario_r4
CleverMouse wrote:Не прибивать дочерний поток. Насильственное прибивание потока - вообще настолько странная операция, что я не могу назвать ни одного случая, когда она действительно нужна.
Зависший и не отвечающий поток разумеется к случаям не относится, да. А программы у нас все пишут просто идеально.

Re: Помогите новичку

Posted: Thu Feb 28, 2013 9:01 pm
by CleverMouse
Неотвечающий поток чем-то занят. Конечно, он может крутиться в бесполезном бесконечном цикле, но могут быть и другие варианты. Например, поток занят сбросом на диск всего, что записала функция файловой системы. В этом случае убивать его чревато.
В том же Linux есть зомби. Пока в Колибри нет механизмов, позволяющих отсрочить смерть, - убивать потоки, занятые непонятно чем, просто нельзя.

Re: Помогите новичку

Posted: Thu Feb 28, 2013 9:13 pm
by Mario_r4
CleverMouse wrote:Неотвечающий поток чем-то занят. Конечно, он может крутиться в бесполезном бесконечном цикле, но могут быть и другие варианты. Например, поток занят сбросом на диск всего, что записала функция файловой системы. В этом случае убивать его чревато.
В том же Linux есть зомби. Пока в Колибри нет механизмов, позволяющих отсрочить смерть, - убивать потоки, занятые непонятно чем, просто нельзя.
Тогда нужно вводить какой-то дополнительный признак который сообщит, взаимодействует поток с ядром или живет богатым внутренним миром, выполняя условно-бесконечный цикл.

Re: Помогите новичку

Posted: Fri Mar 01, 2013 1:42 pm
by CleverMouse
Я закоммитила r3296 и r3303-r3304, теперь ядро гарантированно не упадёт вслед за убитым потоком. Но это не даёт права убивать потоки, занятые неизвестно чем, по той же причине: поток может быть в середине важной операции, прерывание которой может закончиться плачевно. Например, поток мог копировать файл, тогда в итоге будет скопирован только кусок файла. Или поток мог сохранять настройки в уже существующий ini-файл, вставляя куда-нибудь посередине новую строку, тогда в ini-файле будет каша из старого и нового, что наверняка очень удивит программу при следующем запуске. Ещё раз: нельзя убивать потоки, нужно договариваться с ними о смерти.

Re: Помогите новичку

Posted: Fri Mar 01, 2013 5:02 pm
by 0CodErr
Объясните, что означают эти ошибки:

Re: Помогите новичку

Posted: Fri Mar 01, 2013 5:21 pm
by Leency
Главное тут EIP - он силишком большой, так что судя по всему выход за границу памяти.

Re: Помогите новичку

Posted: Fri Mar 01, 2013 5:56 pm
by SoUrcerer
Или это падение в ядре, что более вероятно.

Re: Помогите новичку

Posted: Fri Mar 01, 2013 6:10 pm
by CleverMouse
Главное тут действительно EIP. В диапазоне адресов с 80010000 до примерно 80040000 располагается ядро. При разработке приложений падение в районе ядра практически всегда означает вызов системной функции с неверными параметрами.
В последней русской ночной сборке по адресам 800226E9 и 8001AD88 ничего интересного нет; в последней английской ночной сборке 800226E9 = file_system_lfn+0Ah, 8001AD88 = dtext.text_asciiz, так что неверные параметры в функциях 70 и 4 соответственно. Адреса всех меток ядра можно узнать, скомпилировав ядро с отладочной информацией - галочка в Колибри-версии, ключ -s с утилитой symbols в остальных версиях.

Re: Помогите новичку

Posted: Fri Mar 01, 2013 6:57 pm
by 0CodErr
CleverMouse, спасибо.
Да, это как раз было в английской сборке svn3306.

Такое у меня бывает не очень часто, главный поток при этом продолжает работать.
А дочерний я убиваю из главного с помощью 18.18.

Вот тут viewtopic.php?p=39992#p39992 я приводил скриншот этой программы. Перед появлением нового подменю поток старого убивается 18.18. Тогда это мне показалось удобным. Если причина ошибок в этом, то как можно было по-другому сделать? IPC?

Re: Помогите новичку

Posted: Fri Mar 01, 2013 7:05 pm
by CleverMouse
Для GUI-потоков проще всего делать так:
* в том потоке, который нужно уметь завершать: назначать идентификаторы всех кнопок, если они вообще есть, от 2 и выше,
* в цикле выборки сообщений того же потока: если приходит событие о нажатии кнопки и кнопка имеет идентификатор 1, поток завершает работу;
* в главном потоке, который хочет завершить предыдущий поток: вызвать функцию 72 с параметрами "нажать кнопку с идентификатором 1".
Саму кнопку с идентификатором 1 создавать не нужно.

Но на причину конкретно этих падений убивание функцией 18.18 не тянет.

Re: Помогите новичку

Posted: Fri Mar 01, 2013 9:39 pm
by 0CodErr
Попробовал сделать как ты сказала — работает. И вроде бы даже нашёл, в чём была ошибка: раньше я не ждал пока поток завершится и запускал новый поток. На главный поток это не влияло, но у этих двух был общий стек(да и не только стек). Однако, вот тут viewtopic.php?p=39994#p39994 Serge писал, что завершаемый поток не получит управления. Но всё-таки те ошибки теперь почему-то не появляются.

Posted: Fri Mar 01, 2013 10:02 pm
by CleverMouse
Тогда это было верно. Сейчас — нет.

Re: Помогите новичку

Posted: Sat Mar 02, 2013 3:39 am
by 0CodErr
* в главном потоке, который хочет завершить предыдущий поток: вызвать функцию 72 с параметрами "нажать кнопку с идентификатором 1".
Если предыдущий не успел нарисовать окно, то закрываются чужие окна.

В версии с 18.18 иногда дочерний поток виснет и его невозможно убить через CPU.
У меня запуск/завершение потоков происходит при движении мыши, и, если делать это быстро-быстро, то возникают глюки.

Re: Помогите новичку

Posted: Sat Mar 02, 2013 10:06 am
by Serge
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();

Re: Помогите новичку

Posted: Sat Mar 02, 2013 2:10 pm
by 0CodErr
Спасибо, Serge. Теперь заработало. Я минуты две водил мышкой беспрерывно :)