Jeśli wątki mają ten sam PID, jak można je zidentyfikować?

98

Mam zapytanie związane z realizacją wątków w Linuksie.

Linux nie ma wyraźnej obsługi wątków. W przestrzeni użytkownika możemy użyć biblioteki wątków (takiej jak NPTL) do tworzenia wątków. Teraz, jeśli używamy NPTL, obsługuje mapowanie 1: 1.

Jądro użyje tej clone()funkcji do zaimplementowania wątków.

Załóżmy, że utworzyłem 4 wątki. Wtedy oznaczałoby to, że:

  • Będzie 4 task_struct.
  • Wewnątrz task_structbędzie zapewnione udostępnianie zasobów zgodnie z argumentami do klonowania (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND).

Teraz mam następujące zapytanie:

  1. Czy 4 wątki będą miały ten sam PID? Jeśli ktoś może rozwinąć, w jaki sposób są udostępniane PIDy.
  2. W jaki sposób identyfikowane są różne wątki; czy istnieje koncepcja TID (identyfikator wątku)?
SPSN
źródło

Odpowiedzi:

275

Cztery wątki będą miały ten sam PID, ale tylko patrząc z góry. To , co ty (jako użytkownik) nazywasz PID, nie jest tym, co jądro (patrząc od dołu) nazywa PID.

W jądrze każdy wątek ma swój własny identyfikator, zwany PID (chociaż prawdopodobnie bardziej sensowne byłoby nazywanie go TID lub ID wątku), a także ma TGID (identyfikator grupy wątków), który jest PID wątku to zapoczątkowało cały proces.

Upraszczając, kiedy tworzony jest nowy proces , pojawia się on jako wątek, w którym zarówno PID, jak i TGID mają ten sam (nowy) numer.

Gdy wątek uruchamia inny wątek, ten rozpoczęty wątek otrzymuje swój własny PID (więc planista może zaplanować go niezależnie), ale dziedziczy TGID z oryginalnego wątku.

W ten sposób jądro może szczęśliwie planować wątki niezależnie od tego, do jakiego procesu należą, podczas gdy procesy (identyfikatory grup wątków) są raportowane do Ciebie.

Pomocna może być następująca hierarchia wątków (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

Możesz zobaczyć, że rozpoczęcie nowego procesu (po lewej) daje nowy PID i nowy TGID (oba ustawione na tę samą wartość), podczas gdy rozpoczęcie nowego wątku (po prawej) daje nowy PID przy zachowaniu tego samego TGID jako wątek, który go rozpoczął.


(a) Drżyj z podziwu dla moich imponujących umiejętności graficznych :-)

paxdiablo
źródło
20
FYI, getpid()zwraca tgid:, asmlinkage long sys_getpid(void) { return current->tgid;}jak pokazano na www.makelinux.com/
Duke
6
@Duke - wow, dlatego nie mogłem znaleźć gettgid(2)funkcji. I getpid()nie zwróci TID ("PID" wątku), i tu gettid(2)pojawia się. W ten sposób mogę stwierdzić, czy jesteśmy w głównym wątku, czy nie.
Tomasz Gandor
2
Prowadzi to do kolejnego interesującego punktu: więc jeśli wątki i procesy są obsługiwane jednakowo w jądrze (poza tgid), proces wielowątkowy w końcu uzyska więcej czasu procesora niż proces jednowątkowy, pod warunkiem, że oba mają taki sam priorytet i żaden z wątków nie jest zatrzymywany z jakiegokolwiek powodu (np. oczekiwanie na muteks).
Aconcagua,
1
@Aconcagua, CFS (całkowicie uczciwy program do planowania w Linuksie) generalnie działa w ten sposób, ale pozwala również na użycie rozszerzeń harmonogramu grupowego, aby sprawiedliwość działała w określonych grupach zadań zamiast pojedynczych zadań. Nigdy tak naprawdę nie zajrzałem do tego inaczej niż pobieżnym rzutem oka.
paxdiablo
`` getpgrp '', aby uzyskać identyfikator grupy
Pengcheng
2

Wątki są identyfikowane za pomocą identyfikatorów PID i TGID (identyfikator grupy wątków). Wiedzą również, który wątek jest rodzicem i kto tak zasadniczo dzieli swój PID ze wszystkimi wątkami, które uruchamia. Identyfikatory wątków są zwykle zarządzane przez samą bibliotekę wątków (na przykład pthread itp.). Jeśli 4 wątki są uruchomione, powinny mieć ten sam PID. Jądro samo zajmie się planowaniem wątków i tym podobne, ale biblioteka będzie zarządzać wątkami (niezależnie od tego, czy mogą one działać, czy nie, w zależności od użycia metod łączenia wątków i oczekiwania).

Uwaga: pochodzi to z moich wspomnień dotyczących jądra 2.6.36. Moja praca w aktualnych wersjach jądra jest w warstwie I / O, więc nie wiem, czy to się zmieniło od tamtego czasu.

Jesus Ramos
źródło
-6

Linux zapewnia fork()wywołanie systemowe tradycyjną funkcjonalność powielania procesu. Linux zapewnia również możliwość tworzenia wątków za pomocą clone()wywołania systemowego. Jednak linux nie rozróżnia procesów i wątków.

SAUNDARYA KUMAR GUPTA
źródło