boost :: threads - как сделать изящное завершение работы? - PullRequest
4 голосов
/ 17 июня 2010

Я пытаюсь улучшить переносимость приложения C ++, используя потоки boost: вместо нашей собственной оболочки над потоками Win32, и проблема постепенного завершения потока (снова) поднимает свою уродливую голову.

На чистом win32 я 'прерываю' потоки, используя QueueUserAPC , чтобы вызвать исключение "thread_interrupt", которое приводит к очистке всех объектов RAII, , как описано здесь . Таким образом, любая «предупреждающая» функция ОС может быть прервана, поэтому такие вещи, как мьютексное ожидание, спящий режим, последовательный ввод и вывод сокета, являются возможными точками прерывания.

Тем не менее, boost: мьютексы и т. Д. Не «оповещаются» QueueUserAPC на win32 - они вызывают такие вещи, как Sleep (n), а не SleepEx (n, true))

Повышающие потоки действительно имеют механизм «прерывания» (который также включает в себя генерирование исключения), но, похоже, у него есть недостаток, заключающийся в том, что вызовы ONLY boost :: thread являются прерывистыми, поэтому сторонняя библиотека сокетов (например) не может быть прерываться.

Что делать? Я мог бы модифицировать источник усиления локально, чтобы сделать его прерываемым, но это кажется плохим выбором, и я не думаю, что это помогает переносимости. Редизайн всего приложения, чтобы убрать требование изящного отключения потока, - такой же непривлекательный маршрут ...

1 Ответ

1 голос
/ 17 июня 2010

У меня есть идея для частичного решения для Win32, но я еще не протестировал его:

Мой метод "прерывания нити" может вызывать как boost::thread.interrupt(), И QueueUserAPC, так и функцию, вызываемуюQueueUserAPC просто вызовет boost::interruption_point(), чтобы позволить прерыванию буста получить контроль.

Это должно означать, что поток прерывается (но "по-разному"), когда он ожидает объекта синхронизации буста или 'оповещение "родные окна один.

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