Чотири потоки матимуть той самий PID, але лише при огляді зверху. Те, що ви (як користувач) називаєте PID - це не те, що ядро (дивлячись знизу) називає PID.
У ядрі кожен потік має власний ідентифікатор, який називається PID (хоча, можливо, було б більш розумно називати це TID або ідентифікатор потоку), і вони також мають TGID (ідентифікатор групи потоків), який є PID потоку що розпочало весь процес.
Спрощено, коли створюється новий процес , він відображається у вигляді потоку, де і PID, і TGID є однаковим (новим) номером.
Коли потік запускає інший потік, цей запущений потік отримує свій власний PID (тому планувальник може планувати його самостійно), але він успадковує TGID від вихідного потоку.
Таким чином, ядро може із задоволенням планувати потоки, незалежно від того, до якого процесу вони належать, тоді як вам повідомляються процеси (ідентифікатори груп потоків).
Наступна ієрархія потоків може допомогти (a) :
USER VIEW
<-- PID 43 --> <----------------- PID 42 ----------------->
+---------+
| process |
_| pid=42 |_
_/ | tgid=42 | \_ (new thread) _
_ (fork) _/ +---------+ \
/ +---------+
+---------+ | process |
| process | | pid=44 |
| pid=43 | | tgid=42 |
| tgid=43 | +---------+
+---------+
<-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
KERNEL VIEW
Ви можете бачити, що запуск нового процесу (зліва) дає вам новий PID та новий TGID (обидва встановлені на одне значення), а запуск нового потоку (справа) дає вам новий PID, зберігаючи той самий TGID як нитка, яка його запустила.
(а) тремтіти в захваті від моїх вражаючих графічних навичок :-)
getpid()
повертає tgid:,asmlinkage long sys_getpid(void) { return current->tgid;}
як показано на www.makelinux.com/