У меня есть многопоточное приложение в среде POSIX / Linux - я не контролирую код, который создает pthreads. В какой-то момент процесс - владелец pthreads - получает сигнал.
Обработчик этого сигнала должен прервать, отменить или остановить все pthreads и записать, сколько pthreads выполнялось.
Моя проблема заключается в том, что я не смог найти способ перечисления всех pthread, работающих в процессе.
Кажется, не существует переносимого способа перечисления потоков в процессе.
В Linux есть pthread_kill_other_threads_np
, который выглядит как пережиток исходной реализации 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
, которая записывается в структуру данных, которую вы можно осмотреть потом.
Учитывая, что потоки находятся в вашем процессе, они должны находиться под вашим контролем. Вы можете записать их все в структуру данных и отслеживать.
Тем не менее, выполнение этого не будет свободным от состояния гонки, если оно не будет управляться должным образом (или если вы когда-либо создаете потоки и присоединяетесь к ним только из одного потока).
Любые потоки, созданные библиотеками, которые вы используете, являются их делом, и вы не должны возиться с их каталогом, иначе библиотека может сломаться.
Если вы, конечно, планируете выйти из процесса, вы можете просто оставить потоки работающими, так как вызов exit () завершает их все.
Помните, что надежное приложение в любом случае должно быть защищено от сбоев, поэтому вы не должны зависеть от поведения при завершении работы, чтобы избежать потери данных и т. Д.
Вы можете обернуть ps -eLF
(или другую команду, которая более точно читает только интересующий вас процесс) и прочитать NLWP
, чтобы узнать, сколько потоков выполняется.