API API POSIX для отображения всех pthreads, запущенных в процессе

У меня многопоточное приложение в среде POSIX/Linux - у меня нет контроля над кодом, который создает pthreads. В какой-то момент процесс - владелец pthreads - получает сигнал.

Обработчик этого сигнала должен прерывать, отменять или останавливать все pthreads и регистрировать, сколько pthreads там работает.

Моя проблема в том, что я не мог найти, как перечислять все запущенные pthreads.

Ответы

Ответ 1

Кажется, нет никакого переносного способа перечисления потоков в процессе.

Linux имеет pthread_kill_other_threads_np, который выглядит как оставшаяся часть из первоначальной реализации pure-userland pthreads, которая может работать или не работать так, как описано сегодня. Это не говорит вам, сколько там было потоков.

Вы можете получить много информации о своем процессе, просмотрев /proc/self (или для других процессов /proc/123). Хотя у многих организаций есть файл или каталог с таким именем, макет совершенно другой, поэтому любой код с использованием /proc будет специфичным для Linux. Документация /proc находится в Documentation/filesystems/proc.txt в исходном коде ядра. В частности, /proc/self/task имеет подкаталог для каждого потока. Имя подкаталога - это идентификатор LWP; к сожалению, [1] [2] [3], похоже, нет способа связать идентификаторы LWP с идентификаторами pthread (но вы можете получить свой собственный идентификатор потока с помощью gettid(2), если вы работаете на него). Конечно, чтение /proc/self/task не является атомарным; количество потоков доступно с помощью атома через /proc/self/status (но, конечно, это может измениться, прежде чем действовать на него).

Если вы не можете достичь того, чего хотите, с ограниченной поддержкой, которую вы получаете от Linux pthreads, другая тактика - это использовать динамические трюки для связи, чтобы предоставить свою собственную версию pthread_create, которая регистрируется в структуре данных, которую вы можете проверить впоследствии.

Ответ 2

Вы можете обернуть ps -eLF (или другую команду, которая более внимательно читает только интересующий вас процесс) и прочитать столбец NLWP, чтобы узнать, сколько потоков выполняется.

Ответ 3

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

Однако выполнение этого не будет бесплатным для гонок без его надлежащего управления (или вы только создадите и присоедините потоки из одного потока).

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

Если вы планируете выйти из процесса, конечно, вы можете просто оставить потоки в любом случае, так как вызов exit() завершает их все.

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