В принципе, информация в вашей книге исторически точна из-за постыдно плохой истории реализации потоков в Linux. Этот мой ответ на связанный вопрос о SO также служит ответом на ваш вопрос:
Все эти недоразумения происходят из-за того, что разработчики ядра изначально придерживались иррационального и неправильного мнения о том, что потоки могут быть реализованы почти полностью в пользовательском пространстве с использованием процессов ядра в качестве примитива, если ядро предлагает способ заставить их совместно использовать памяти и файловых дескрипторов. Это привело к заведомо плохой реализации потоков POSIX в LinuxThreads, название которой было скорее неправильным, поскольку оно не давало ничего, отдаленно напоминающего семантику потоков POSIX. В конце концов LinuxThreads был заменен (на NPTL), но многие запутанные термины и недопонимания сохраняются.
Первое и самое важное, что нужно понять, это то, что "PID" означает разные вещи в пространстве ядра и пространстве пользователя. То, что ядро называет PID, на самом деле является идентификатором потока на уровне ядра (часто называемым TID), не путать с
pthread_t
, который является отдельным идентификатором. Каждый поток в системе, независимо от того, находится ли он в одном процессе или в другом, имеет уникальный TID (или «PID» в терминологии ядра).То, что считается PID в смысле POSIX «процесс», с другой стороны, в ядре называется «ID группы потоков» или «TGID».Каждый процесс состоит из одного или нескольких потоков (процессов ядра), каждый со своим собственным TID (PID ядра), но все они используют один и тот же TGID, который равен TID (PID ядра) исходного потока, в котором
main
работает.Когда
top
показывает вам потоки, он показывает TID (PID ядра), а не PID (TGID ядра), поэтому каждый поток имеет отдельный.С появлением NPTL большинство системных вызовов, которые принимают аргумент PID или воздействуют на вызывающий процесс, были изменены для обработки PID как TGID и воздействуют на всю «группу потоков» (процесс POSIX). ).