2016-06-20 2 views
0

У меня есть файлы TCL, которые получены в файлах на C++. , для которого я использовал функцию Tcl_DoOneEvent в конце, чтобы позаботиться обо всех вызовах TCL. У меня также есть несколько потоков, вызываемых в функции Main. чтобы выйти из всех потоков и функций, у меня есть функция quit. поэтому в текущем случае я вижу, что все pthreads и другая функция завершаются, за исключением функции Tcl_DoOneEvent, вызванной в конце. который выдает ошибку сегментации. есть способ выйти из функции while (1) из другой функции.Выход из функции Tcl_DoOneEvent

main() 
{ 
... 
... 
pthread_create(thread1); 
pthread_create(thread2); 
while(1) Tcl_DoOneEvent(TCL_ALL_EVENTS); 
return(0); 
} 

quit_fn() 
{ 
... 
... 
pthread_cancel(thread1); 
pthread_cancel(thread2); 
... 
// exit(0) ; -> this also results in segmentation error 
} 

ответ

1

Для того, чтобы выйти из время цикла, вы должны изменить состояние цикла и сделать его зависит от переменной, которую можно изменить из другого потока (объявить его как летучие).

volatile bool exitLoop = false; 

while (!exitLoop) 
{ 
    Tcl_DoOneEvent(TCL_ALL_EVENTS); 
} 

Я не уверен, но это может быть заблокировано на неопределенный срок, если событий больше нет. Два возможного решения может использовать флаг TCL_DONT_WAIT:

Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT); 
// sleep some time here in order to avoid busy wait 

Или лучше, вызвать событие из ваших бросить курить функции, так что Tcl_DoOneEvent просыпается, и в следующей итерации переменной exitLoop верно.

Наконец, я бы рекомендовал вам следовать одному и тому же циклу и условию выхода из условия для всех ваших потоков. Вместо использования pthread_cancel для завершения потока попробуйте использовать pthread_join. Таким образом, вы точно контролируете, в какой момент поток выходит, и вы можете выполнить некоторую очистку и избежать ошибок сегментации или других видов ошибок.

+0

Наличие функции quit посылает событие в основной поток, это рекомендуемый подход. Событие может иметь тривиальный обработчик, или обработчик события может быть тем, что устанавливает 'exitLoop', который тогда не должен быть' volatile', поскольку он доступен только из одного потока. 'TCL_DONT_WAIT' не рекомендуется для этого случая использования; Tcl отлично подходит для событий без него. –

+0

Я согласен с этим, отправляя мероприятие и позволяя Tcl справляться со сном лучше. volatile не требуется, при условии, что флаг никогда не используется из других потоков (но мы не знаем, так ли это из кода). –

Смежные вопросы