Jak generowane są PID?

42

W systemie * nix identyfikatory PID są unikatowymi identyfikatorami dla uruchomionych procesów. Jak generowane są PID? Czy to tylko liczba całkowita, która się zwiększa, czy bardziej złożona struktura, taka jak lista? Jak są poddawane recyklingowi? Przez recykling rozumiem, że kiedy proces się zakończy, jego PID zostanie ostatecznie wykorzystany przez inny proces.

Giovanni Funchal
źródło

Odpowiedzi:

39

Jak mówi wikipedia ,

W systemie Unix identyfikatory procesów są zwykle przydzielane sekwencyjnie, zaczynając od 0 i rosnąc do maksymalnej wartości, która różni się w zależności od systemu. Po osiągnięciu tego limitu alokacja rozpoczyna się od zera i ponownie wzrasta. Jednak w przypadku tego i kolejnych przebiegów wszelkie identyfikatory PID nadal przypisane do procesów są pomijane.

więc jest to naprawdę bardzo prosta zasada „generowania”, po prostu zwiększania licznika i „recyklingu”, po prostu owiń liczbę wokół wartości maksymalnej i kontynuuj zwiększanie, dopóki nie znajdziesz numeru, który został przypisany do procesu, który został zakończony i ma został usunięty z tabeli procesów.

Niektóre implementacje uniksowe, takie jak AIX, używają zasad, które są mniej proste, patrz np. Ten FAQ .

Alex Martelli
źródło
Dziękuję za odpowiedź. Nawiasem mówiąc, czym dokładnie jest ta zasada AIX „mniej prosta”?
1
@Helltone, nie sądzę, aby system AIX dokładnie dokumentował, jakich zasad używa (aby mógł się zmienić w dowolnej wersji), ale można by pomyśleć o nim jako o generowaniu liczb losowych w odpowiednim zakresie (który powtarza się, dopóki nie zostanie wygenerowany PID, który obecnie nie w użyciu).
Alex Martelli
Ten algorytm wydaje mi się nieco problematyczny. Jak zapewnić, że nie wpadniesz w impas? I czy nie ma problemu z wydajnością?
1
Jądro jest pod kontrolą i nie musi niczego blokować, więc jak mógł się zakleszczyć? Tak, do zapłacenia jest niewielka cena za wydajność (niewielki dodatkowy koszt w czasie rozwidlenia - powiedz kilka tuzinów instrukcji maszynowych dla przystawnego PRNG lub / dev / urandom read, w porównaniu do znacznie mniejszej dla uzyskania przyrostu), ale to zawsze przypadek środków mających na celu poprawę bezpieczeństwa (sprawdź na przykład obciążenie procesora komunikacją HTTPS w porównaniu do zwykłego HTTP ;-).
Alex Martelli
Miałem na myśli livelock ( while(true);), przepraszam, szybko odpowiadałem ;-)
11

To się zmienia.

Większość systemów po prostu rejestruje ostatnio wygenerowany PID, dodaje jeden (zawijanie do maksymalnej liczby, takiej jak 65535 lub nieco mniejszej - często zawijanie ma miejsce przy 65000 lub nawet 60000) i sprawdza, czy numer nie jest aktualnie używany ( powtarzanie, jeśli PID jest nadal w użyciu - więc jądro PID 1 wciąż tam jest i nie zostaje ponownie uruchomione).

Inne systemy zorientowane na bezpieczeństwo generują losowo liczbę i sprawdzają, czy nie jest używana.

W danym momencie gwarantuje się, że wszystkie numery PID są unikalne.

Jonathan Leffler
źródło
9

Jeśli chodzi o część pytania dotyczącego recyklingu, należy pamiętać, że pid nie staje się dostępny, gdy tylko zakończy się proces z tym pid. Pid nie staje się dostępny, dopóki rodzic tego procesu nie odbierze statusu zakończenia swojego potomka poprzez jakąś formę wywołania systemowego wait (). Dziecko, które zostało zakończone, ale którego rodzic nie wydał czekania, nazywa się zombie i zwykle pojawia się w ps jako nieistniejące. Niegrzeczny rodzic może głodować system pid, jeśli uruchamia on dzieci i nie czeka na nie ().

Jeśli rodzic procesu umiera, zanim pobierze status dziecka, jest to w porządku. Dziecko jest dziedziczone przez init, który upewni się, że zostanie wydane wait (), a pid zostanie przetworzony.

frankc
źródło
To bardzo ważny szczegół. Bez tego nawet prosty myprog &następowałby po wait $!UB.
Andreas
3

Są to numery sekwencyjne i są zawijane (według wartości specyficznej dla systemu operacyjnego), jeśli system działa wystarczająco długo. Liczby nigdy nie są ponownie używane, chyba że są darmowe fork().

Donal Fellows
źródło