Предоставляются ли гарантированные сигналы POSIX в частично инициализированную нить?

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

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

...

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

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

Ответ 1

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

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

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

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

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

Ответ 2

спецификация POSIX pthread_create предоставляет это мне в виду:

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

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

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

Ответ 3

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

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