Гарантийные сигналы POSIX не будут доставлены в частично инициализированный поток? - PullRequest
10 голосов
/ 19 ноября 2010

В большинстве реализаций потоков POSIX требуется некоторая инициализация во вновь созданном потоке, прежде чем он будет в согласованном состоянии, способном выполнять код приложения. Это может включать разблокировку блокировок в структуре потока, инициализацию «регистра потока» в реализациях, в которых он используется, инициализацию локальных данных потока (либо TLS-уровня уровня данных, либо данных, специфичных для потока POSIX), и т. Д. гарантировать, что вся эта инициализация будет завершена до того, как поток сможет получить какие-либо сигналы; самое близкое, что я могу найти, это 2.4.3:

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

...

Предположительно, некоторые из этих функций (по крайней мере fork, которые должны проверять глобальное состояние, установленное функцией pthread_atfork) зависят от того, находится ли поток в согласованном, инициализированном состоянии.

Одна вещь, которая беспокоит меня, это то, что я прочитал большую часть источника glibc / nptl и не могу найти никакой явной синхронизации, чтобы предотвратить обработку сигнала вновь созданным потоком до его полной инициализации. Я ожидаю, что поток, вызывающий pthread_create, заблокирует все сигналы перед вызовом clone, и новый поток разблокирует их после завершения инициализации, но я не могу найти никакого кода на этот счет и не вижу его в strace вывод.

Ответы [ 3 ]

1 голос
/ 19 ноября 2010

(я не думаю, что это реальный ответ, но он слишком большой для комментария)

Это очень интересный вопрос. Я просмотрел код glibc для pthread_create, чтобы увидеть, как он себя ведет, и, если я не пропускаю что-то полностью, кажется, что нет никакого специального поведения, чтобы это остановить (например, блокировка всех сигналов до clone и разблокировка их в in the child после некоторой настройки {после записи времени создания потока и установки обработчика C ++ catch all все, что происходит даже в коде C}).

Я ожидал найти комментарий, в котором упоминалась возможность этой ситуации и, возможно, даже упоминание о том, что POSIX сказал делать (или упоминание о том, что он не сказал, что делать).

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

Это вполне может быть избыточный сайт в pthreads (или glibc, или мое понимание кода).

0 голосов
/ 19 ноября 2010

Спецификация POSIX pthread_create требует этого из моего понимания:

Состояние сигнала нового потока должно быть инициализировано следующим образом:

  • Маска сигналов должна быть унаследована от создаваемого потока.
  • Набор ожидающих сигналов для нового потока должен быть пустым.

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

0 голосов
/ 19 ноября 2010

pthread_create - это блокирующий вызов.Для него нет (нового) потока для отправки сигнала перед вызовом, и является потоком для отправки сигнала на после вызова, таким образом, возвращается идентификатор потокапо вызову.

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

...