2015-09-24 3 views
8

В ходе комментария к a recent question возник вопрос о том, в какой момент можно ожидать отмена запроса на поток pthreads с возможностью отмены PTHREAD_CANCEL_DEFERRED. Ссылки на the standard и немного адвокатской деятельности. Я не очень беспокоюсь о том, ошибался ли я в своих комментариях по этому вопросу, но я хотел бы, чтобы быть уверенным, что я правильно понимаю положения POSIX.Что означает POSIX, что поток «приостановлен»?

Наиболее уместный раздел стандарта говорит

Всякий раз, когда нить разрешена и запрос на аннулирование был сделан с этой нитью в качестве цели, и поток затем вызывает любую функцию, которая является точкой отмены [...], запрос на отмену должен быть выполнен до возвращения функции. Если поток имеет возможность отмены, и запрос на отмену выполняется с потоком в качестве цели, в то время как поток приостанавливается в точке отмены, поток должен быть разбужен, и на запрос аннулирования будет действовать.

Что, однако, означает, что нить должна быть «приостановлена»? POSIX явно определяет термин для процессов, но не, насколько я могу определить, для потоков. С другой стороны, приостановка потоков документов POSIX относится к поведению нескольких функций, включая, помимо прочего, некоторые из тех, которые связаны с объектами синхронизации. Следует ли тогда заключить, что они служат коллективно как соответствующее определение термина?

И как это все имеет отношение к вопросу, породившей эту строку запроса, учитывая, что POSIX не определяет нити подвески как часть поведения read(), fread(), или любой из общего файла или потока функций ввода/вывода, если поток не успевает за счет блокировки ввода-вывода, означает ли это, что это «приостановлено» для целей отмены?

+2

Стандарт IEEE 1003.1 (POSIX) явно утверждает, что он согласован со стандартом ISO/IEC 9899 (C). Стандарт C цитирует [ИСО/МЭК 2382 (Словарь по информационным технологиям)] (https://www.iso.org/obp/ui/#iso:std:iso-iec:2382:ed-1:v1:en) для его жаргон. К сожалению, даже ISO/IEC 2382 не определяет _suspended_ и даже использует это слово в некоторых определениях. Из этого я заключаю, что «приостановлено» считается ключевым английским словом, подходящим для использования в объяснениях. Моя личная интерпретация приостановленного - это «состояние потока, в котором в настоящее время не используется процессорное время». –

+0

@IwillnotexistIdonotexist, выравнивание с C - полезное наблюдение, спасибо. Тем не менее, я считаю, что «не используется время процессора» не вызывает беспокойства, поскольку похоже, что он будет охватывать потоки, которые * могут быть запущены, но были выгружены. Кажется, что это не соответствует действительности - все указывает на то, что потоковая приостановка - это состояние, в котором поток предотвращается *, даже если CPU был бы доступен для него. Возможно, действительно, что стандарты C и POSIX предполагают, что должна применяться естественная интерпретация, но детали имеют значение, и они неясны (для меня). –

+1

Мне кажется естественным думать, что запущенные потоки, которые не работают, из-за отсутствия лучшего слова приостановлены.На сильно загруженном процессоре 'n'-core могут быть процессы'> n'_runnable_, но самое большее 'n' из них можно сделать _running_; Все остальные должны быть _not-running_, или как POSIX _might_ иметь его, «их исполнение приостановлено» в ожидании своей очереди. Как вы думаете? Является ли runnable thread ожидающим, пока квант времени текущего потока истекает? Как насчет того, что работающий поток, чей квант истекает и, хотя он все еще работает, отключается? Как насчет остановленных потоков? –

ответ

1

read, fread и friends являются системными вызовами и, как таковые, они будут выполнять контекстный переключатель и выполнять из контекста ядра до тех пор, пока эти функции не будут завершены. Прерывание контекста ядра выходит за рамки pthreads, поэтому они не будут вызывать отмену.

У меня нет ссылки на него, но насколько я знаю, поточная приостановка в контексте потоков Posix связана с объектом синхронизации (например, futex's).

+1

Спасибо, но я ищу аргументы на основе * документации *, не основанные на конкретных * реализациях *. –

+0

Эт, эти системные вызовы * являются прерывистыми. 'man read: [...] Это не ошибка, если это число меньше, чем количество запрошенных байтов; это может произойти, например, [...], потому что read() был прерван сигналом. [...] EINTR. Позывной был прерван сигналом перед чтением любых данных; см. сигнал (7) .' – EOF

2

Определение приостановки в контексте потоков:

3,107 Состояние Переменная

объект синхронизации, который позволяет потоку приостановить исполнение, неоднократно, пока какой-нибудь связанный предикат не станет истинным. Поток, выполнение которого приостановлено на переменной условия, считается заблокированным в переменной условия.

От: http://pubs.opengroup.org/onlinepubs/9699919799/

Это не прямой ответ, просто определение - слишком велик для комментария. Заблокировано == приостановлено.

+1

Да, я это видел. Я учитываю это как определение поведения 'pthread_cond_wait()' для включения приостановки потока. Другие функции ('wait()', 'sleep()', ...) также документируются, чтобы вызвать приостановку потока, однако это не может быть полным определением. –

+0

«Объект синхронизации» не обязательно является локальным для кода - вместо этого он может быть реализованным ядром. То, что нам нужно найти, - это обсуждение (намерение) за развитием определения, чтобы быть уверенным. Любая помощь там? –

+0

Я изучаю аспекты POSIX в течение некоторого времени, но, боюсь, у меня нет особого понимания его развития. В этом случае я вижу веские причины с точки зрения разработчиков, которые хотят, чтобы «приостановленные» были определены включительно, но веские причины, с которыми сталкиваются стандартные авторы и разработчики, хотят, чтобы они были определены узко. –

3

Подвесной поток - это тот, который, как вы говорите, заблокирован в сокете, читайте, ожидая, когда семафор станет доступным, и т. Д.

Учитывая, что реализации POSIX различаются по сложным ребрам и что существует вероятность блокирования потока в функции, которая не является точкой отмены, возможно, это связано с отменой кода, который должен быть перенесен может быть больше проблем, чем это стоит.

Я никогда не использовал его, я всегда хотел, чтобы код явно инструктировал поток прекратить (как правило, сообщение вниз по трубе или очереди). Это очень просто с помощью системы последовательных сообщений или системы Actor Model.

Таким образом, очистка может осуществляться под своим контролем, освобождение памяти и т. Д. По мере необходимости. Я не знаю, будет ли отмененный поток очищать свою память (я подозреваю, нет), или есть опция для типа типа at_exit() (может быть). В целом, я думаю, что поведение приложения более тщательно контролируется, если есть только один способ, по которому поток может выйти.

== EDIT ==

@JohnBollinger,

язык, используемый If a thread has cancelability enabled and a cancellation request is made with the thread as a target while the thread is suspended at a cancellation point может быть, как IF a thread has cancelability enabled AND IF cancelled and IF implementation suspends blocked threads AND IF the thread is blocked THEN the thread shall be awakened... интерпретируются с. Другими словами, они оставляют это до реализации подсистемы POSIX.

Реализация Cygwin select() не приводит (или, по крайней мере, нет) к приостановке потока. Вместо этого он генерирует поток опроса для дескриптора файла для проверки активности, связанной с сигналами, из-за фундаментального отсутствия чего-либо, подобного select() в Windows (он приближается, но не сигары. Win32 select() работает только с сокетами). Реализации select() еще в 1980-х годах часто работали так же.

Возможно, это связано с тем, что POSIX неохотно определяет, когда поток приостановлен. Исторически многие реализации select() были такими, что делало это минным полем для комитета по стандартизации, чтобы сказать, когда поток может или не может быть приостановлен. Конечно, сложности, вызванные select(), также относятся к процессу, но поскольку POSIX действительно определяет приостановленный процесс, кажется странным, что они не могли/не расширили определение до потоков.

Возможно, это связано с тем, как реализованы потоки; вы, возможно, можете иметь реализацию POSIX, которая не использует потоки ОС (немного похожая на ранние реализации ADA в те дни, когда ОС не выполняла потоков вообще), и в такой реализации заблокированный поток может не быть приостановлен (в смысле отсутствия циклов процессора).

+2

«Подвешенная нить - это та, которая, как вы говорите, заблокирована в считываемом сокете, ожидая, что семафор станет доступным и т. Д.».На самом деле нет, я не говорю об этом. В частности, я сомневаюсь, что POSIX определяет поток, заблокированный при чтении, который будет приостановлен. Я был бы рад услышать вашу основу для такого заявления - вот что я ищу. –

+0

Очистка от отмены потока может быть выполнена (сюрпризом!) 'Pthread_cleanup_push()/pthread_cleanup_pop()'. – EOF

+0

@JohnBollinger, это справедливо. Я не сказал, что POSIX также определяет его так, но, конечно, для реализаций является приостановкой заблокированного потока. Я добавил к своему ответу – bazza