Опасно ли использовать pthread_kill ()? - PullRequest
0 голосов
/ 07 мая 2018

Я прочитал, что TerminateThread() в WinAPI опасно для использования.

Опасно ли использование pthread_kill() в Linux?


Редактировать: Извините, я имел в виду pthread_kill(), а не pthread_exit().

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Поскольку вопрос теперь изменился, я напишу новый ответ. Мой ответ по-прежнему остается "да и нет", но причины изменились.

pthread_kill несколько опасен тем, что разделяет потенциальные временные риски, присущие всем системам обработки сигналов. Кроме того, существуют сложности, связанные с этим, в частности, вы должны настроить обработчик сигнала в потоке. Однако можно утверждать, что это менее опасно, чем упомянутая вами функция Windows. Вот почему:

Функция Windows по существу останавливает поток, возможно, в обход надлежащей очистки. Он предназначен в качестве крайней меры. pthread_kill, с другой стороны, вообще не завершает поток. Он просто отправляет сигнал потоку, на который поток может ответить.

Для того, чтобы это сделать, вам нужно зарегистрировать в потоке, какие сигналы вы хотите обработать. Если ваша цель - использовать pthread_kill для завершения потока, вы можете использовать это, установив обработчику сигнала флаг, к которому у потока может быть доступ, и попросив поток проверить флаг и завершить работу, когда он будет установлен. Возможно, вы сможете вызвать pthread_exit из обработчика сигнала (я никогда не пробовал этого), но мне кажется, что это плохая идея, поскольку сигнал поступает асинхронно, и ваш поток по-прежнему не гарантированно будет работать. Опция flag, о которой я упоминаю, решает эту проблему при условии, что флаг не является локальным для потока, что позволяет обработчику сигнала установить его, даже если целевой поток уже вышел. Конечно, если вы делаете это, вам действительно не нужен pthread_kill вообще, так как вы можете просто сделать так, чтобы ваш основной поток установил флаг в соответствующее время.

Есть еще один вариант остановки другого потока - метод pthread_cancel. Этот метод помещает запрос на отмену в целевой поток и, если поток был настроен на отмену (вы обычно делаете это в pthread_create, но вы также можете сделать это после факта), тогда в следующий раз, когда поток достигнет потенциальная точка отмены (указанная pthread_testcancel, но также автоматически обрабатываемая многими системными подпрограммами, такими как вызовы ввода-вывода), она выйдет. Это также более безопасно, чем то, что делает Windows, так как не вызывает насильственную остановку потока - она ​​останавливается только в четко определенных точках. Но это больше, чем версия для Windows, так как вам нужно правильно настроить поток.

На странице Википедии для "posix threads" описывается кое-что из этого (но не очень), но есть довольно хороший раздел "Смотрите также" и "Ссылки", в котором вы найдете более подробную информацию.

0 голосов
/ 07 мая 2018

Цитируя сэра Хамфри Эпплби, ответ "да, и нет".

Сам по себе вызов pthread_exit () не опасен и вызывается неявно, когда ваш поток завершает свой метод. Однако есть несколько «ошибок», если вы вызываете их вручную.

  1. Все обработчики очистки вызываются, когда это вызывается. Поэтому, если вы вызываете этот метод, а затем обращаетесь к некоторой памяти, которую очистили обработчики очистки, вы получаете ошибку памяти.
  2. Точно так же после того, как это вызвано, любые локальные и локальные переменные потока становятся недопустимыми. Так что, если сделать ссылку на них, вы можете получить ошибку памяти.
  3. Если это уже было вызвано для потока (явным или неявным), повторный вызов его имеет неопределенное поведение, и
  4. Если это последний поток в вашем процессе, это приведет к завершению процесса.

Если вы осторожны с вышесказанным (то есть, если вы стараетесь не ссылаться на что-либо о потоке после вызова pthread_exit), тогда безопасно вызывать call вручную. Однако, если вы используете C ++ вместо C, я настоятельно рекомендую использовать класс std :: thread вместо того, чтобы делать это вручную. Его легче читать, он требует меньше кода и гарантирует, что вы не нарушите ничего из вышеперечисленного.

Для получения дополнительной информации наберите "man pthread_exit", который, по сути, расскажет вам выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...