Procesbesturing in Linux. Beëindig proces in Linux - ps, kill en killall commando's

instructies:

Het Internet Protocol (IP) definieert de levering van gegevens van de ene host naar de andere. Tegelijkertijd biedt het geen garantie voor de nauwkeurigheid van de bezorging: tijdens verzending kunnen pakketten verloren gaan of in een andere volgorde worden ontvangen dan ze zijn verzonden. Het trans-protocol is verantwoordelijk voor de nauwkeurigheid been niveau Transmissie Controle Protocol - TCP. TCP brengt een verbinding tot stand, regelt het verzenden en ontvangen van pakketten, dupliceert zijn acties in het geval dat een reactie op een verzoek niet wordt ontvangen of pakketten verloren gaan. Het is belangrijk om te begrijpen dat TCP niet alleen pakketuitwisseling tussen knooppunten tot stand brengt, maar ook tussen softwaretoepassingen. De netwerkpoort is een voorwaardelijk nummer van 1 tot 65535 dat aangeeft aan welke applicatie het pakket is toegewezen.

U kunt erachter komen welke processen poorten op uw computer gebruiken met behulp van standaard Windows-tools. Klik in het menu Start op Uitvoeren en typ cmd in de opdrachtregel. Bevestig met OK. Typ in een consolevenster netstat -a -n -o.

De PID-kolom bevat het procesnummer, de kolom "" bevat het IP-adres van uw computer en, gescheiden door een dubbele punt, het poortnummer dat wordt ingenomen door het bijbehorende proces. Het "externe adres" is het IP- en poortnummer van het externe knooppunt waarmee een toepassing wordt uitgevoerd.

Typ in het consolevenster de opdracht tasklist. Het toont alle PID-codetoepassingen die op de computer worden uitgevoerd. Op deze manier weet u welk proces een poort op uw computer bezet.

U kunt deze informatie op een andere manier verkrijgen: start de "Taakbeheer" vanaf de opdrachtregel door taskmgr te typen of door op de toetsen Ctrl + Alt + Delete te drukken. Zoek in de PID-kolom het nummer van het proces waarin u geïnteresseerd bent, in de kolom Afbeeldingsnaam - de naam van de bijbehorende toepassing of service. Als de PID niet wordt weergegeven in het Manager-venster, gaat u naar het item "Bekijken" van het hoofdmenu en selecteert u de optie "Kolommen selecteren". Vink het vakje naast Proces-ID (PID) aan.

Wanneer een proces op de computer start, ontvangt het zijn pid, dat wil zeggen de identifier Verwerken... Soms wordt het nodig om deze identifier te achterhalen. Misschien moet u om de een of andere reden een lopend proces uitschakelen, bijvoorbeeld als het het verwijderen van het programma belemmert. Er zijn verschillende manieren om de pid te achterhalen. De eenvoudigste is om het te doen met behulp van de taakbeheerder en de opdrachtregel.

Je zal nodig hebben

  • - een computer met Windows-besturingssysteem (XP, Windows 7).

instructies:

Druk op ctrl + alt + del op je toetsenbord. Als uw besturingssysteem Windows XP is, verschijnt de taakbeheerder onmiddellijk, als Windows 7 - een venster verschijnt waarin u het kunt selecteren.

Selecteer in het tabblad "Processen". Klik nu hier op het item "Bekijken". Er verschijnt een extra venster. Selecteer daarin de optie "Kolommen selecteren". Er verschijnt een dialoogvenster waarin het bovenste item de naam "ID . krijgt Verwerken(pied) ". Vink het vakje ernaast aan. Sla de instellingen op door op OK te klikken.

Ga vervolgens in apparaatbeheer naar het tabblad "Processen", waar u de regel "ID . ziet" Verwerken". Zoek de naam erin Verwerken, waarvan u de ID moet weten en de waarde ervan moet zien.

Het wordt nu als deze waarde beschouwd met behulp van de opdrachtregel van het besturingssysteem. Klik op de knop "Start" en ga naar het tabblad "Alle programma's". Selecteer "Standaardprogramma's". Zoek hier het opdrachtregelmenu-item en voer het uit. Typ takenlijst en druk op Enter. Na het activeren van deze opdracht verschijnt een lijst met alle momenteel actieve processen in het opdrachtpromptvenster. Na de naam van elk van hen wordt de identifier geschreven.

Als u het proces snel moet voltooien, kunt u het als volgt doen. Nadat je de identifier hebt gevonden: Verwerken, typ taskkill / pid 0000 op de opdrachtregel. Voer in plaats van nullen het identificatienummer in Verwerken wat vereist is "". Daarna stuurt het systeem een ​​signaal om het te voltooien en wordt het uitgeschakeld.

Opmerking

Wees voorzichtig bij het beëindigen van processen. Onbedoeld kunt u het actieve proces uitschakelen, dat nodig is voor de juiste werking van het besturingssysteem.

Mailservers adresseren in The Bat! (zoals in andere e-mailprogramma's) gebeurt via specifieke poorten voor het verzenden en ontvangen van e-mail. Om het e-mailprogramma te configureren, moet u de SMTP- en POP3-poortnummers invoeren, evenals de namen van de servers in de boxparameters.

Je zal nodig hebben

  • - gegevens uit e-mail.

instructies:

Ga naar de website van uw mailserver. Uw mailserver is bijvoorbeeld mail.ru. U moet inloggen - dat wil zeggen, uw gebruikersnaam en wachtwoord invoeren - om uw persoonlijke mailbox te openen. Zoek de help-link en klik erop.

Links staat een lijst met helponderwerpen. Klik op het opschrift "Toegang vanuit e-mailprogramma's" en selecteer het eerste item om de instellingenpagina te laden. De pagina geeft aan dat de naam van de inkomende e-mailserver pop.mail.ru is en de uitgaande server smtp.mail.ru is. Dit geldt alleen voor deze dienst. In de regel kan elke postserver verschillende poorten hebben, dus ga naar de officiële website in het ondersteuningscentrum en ontdek de gegevens. Er zijn ook sites op internet die informatie geven over bijna alle diensten die op internet bestaan.

De poortnummers van de uitgaande en inkomende mailservers staan ​​onderaan de pagina vermeld. Het geeft aan dat voor de inkomende mailserver de protocollen 110 zijn (als het mailprogramma zonder encryptie werkt) en 995 (met encryptie). Om erachter te komen welk nummer je moet invoeren, bestudeer je de instellingen van je mailprogramma. Het poortnummer voor uitgaande mail is 25, 587 of 2525 (als de mailer geen encryptie gebruikt) en 465 (met encryptie). Standaard e-mailpoorten zijn 110 en 25. Standaardpoortnummers kunnen ook standaard in het programma worden geschreven, dus indien nodig moet u ze naar de juiste corrigeren.

Als je een andere mailserver gebruikt, bezoek dan de website voor de instellingen. Dergelijke parameters zijn altijd openbaar en worden meestal in de help-sectie geplaatst. Als uw bedrijf zakelijke e-mail gebruikt, neemt u contact op met uw netwerkbeheerder voor poortnummers.

TCP / IP is een verzameling van: protocollen, waarmee u afzonderlijke computers en netwerken in een gemeenschappelijk computernetwerk kunt aansluiten. Met hulp protocollen TCP / IP De meeste applicaties communiceren via internet.

Hoe het ook zij, maar sommige toepassingen zijn in Linux soms bevriezen. In dit geval zijn er situaties waarin de applicatie helemaal niet reageert of zo traag werkt dat het niet mogelijk is om het werk correct te beëindigen. Om snel uit de resulterende situatie te komen, kunt u dit proces "doden". Hiervoor worden de commando's gebruikt doden en killall... Nu zullen we uitzoeken hoe we deze commando's kunnen gebruiken, de PID van het proces vinden en het SIGKILL-signaal verzenden.

Laten we, om verwarring te voorkomen, met het proces overeenkomen dat het programma in het systeem wordt gelanceerd. Als u bijvoorbeeld meerdere vensters van de Mozilla Firefox-browser heeft, betekent dit dat er drie processen actief zijn.

Bepaal de PID van een proces - pidof-opdracht

PID- unieke identificatie van het proces in het systeem Linux... Om het proces correct te stoppen, moet u eerst de PID bepalen. Hiervoor worden de ps en grep commando's gebruikt. Beurtelings ps commando is ontworpen om een ​​lijst met actieve processen in het systeem en informatie over hen weer te geven. Grep-commando draait tegelijkertijd met ps (in een pijp) en zal de resultaten van het ps-commando zoeken. U kunt een lijst met alle processen weergeven door op de opdrachtregel uit te voeren:

Uiteraard kan de PID ook bepaald worden via bovenkant... Maar in de meeste gevallen is het aantal processen te groot (en verandert dynamisch bovenaan), waardoor het niet zo eenvoudig is om de PID snel en correct te bepalen. Dit is waar het grep-commando wordt gebruikt. Om bijvoorbeeld het proces van de Google Chrome-browser te voltooien, moet u de volgende opdracht uitvoeren:

ps axu | grep chroom

[////// ~] $ ps axu | grep chroom
itechf2 20474 2,7 1,5 938416 120136 tty2 Sl + 11:07 0:00 / opt / google / chroom / chroom

In ons geval is 20474 de vereiste PID. Een gemakkelijkere manier is om de opdracht te gebruiken: pidof, in dit geval moet u de naam van het proces opgeven. Bijvoorbeeld:

[///// ~] $ pidof chrome
20728 20706 20668 20647 20586 20574 20553 20508 20474

Beëindig proces in Linux - kill en killall commando's

Beëindig het proces in het besturingssysteem Linux als je de PID kent, kun je de opdracht gebruiken: doden... Het is de moeite waard om te weten en te begrijpen: het kill-commando is ontworpen om een ​​signaal naar een proces te sturen. Als we niet specificeren welk signaal moet worden verzonden, wordt standaard het SIGTERM-signaal verzonden (van het woord beëindiging). SIGTERM geeft aan om het proces te beëindigen. Elk signaal heeft zijn eigen nummer. SIGTERM is genummerd 15. Een lijst van alle signalen (en hun nummers) die het kill-commando kan verzenden, kan worden weergegeven door te rennen doden -l ... Om het SIGKILL-signaal (nummer 9) naar proces 2811 te sturen, voer je uit op de opdrachtregel:

Tegelijkertijd mag het SIGTERM-signaal het proces niet stoppen (bijvoorbeeld wanneer het signaal wordt onderschept of geblokkeerd), terwijl SIGKILL het proces altijd beëindigt, omdat het niet kan worden onderschept of genegeerd.

Killall commando in Linux is het ontworpen om alle processen met dezelfde naam te "doden". Dit is handig omdat we de PID van het proces niet hoeven te weten. We willen bijvoorbeeld alle processen met de naam chrome sluiten. Uitvoeren in terminal:

Het commando killall verzendt, net als kill, standaard het SIGTERM-signaal. Om nog een signaal te sturen, moet je de optie gebruiken: -s ... Bijvoorbeeld:



In dit artikel zullen we proberen een kernelmodule te maken die de PID van een al actief proces in Linux kan wijzigen, en ook experimenteren met processen die een gewijzigde PID hebben ontvangen.


Een waarschuwing: Het wijzigen van de PID is een niet-standaard proces en kan onder bepaalde omstandigheden leiden tot kernel panic.

Onze testeenheid zal het karakterapparaat / dev / test implementeren, wat de PID van het proces zal veranderen wanneer het wordt gelezen. Voor een voorbeeld van de implementatie van een karakterapparaat, dankzij dit artikel. De volledige modulecode staat aan het einde van het artikel. De meest correcte oplossing was natuurlijk om een ​​systeemaanroep aan de kernel zelf toe te voegen, maar hiervoor zou de kernel opnieuw moeten worden gecompileerd.

Omgeving

Alle stappen voor het testen van de module zijn uitgevoerd in een VirtualBox virtuele machine met een 64-bit Linux-distributie en kernelversie 4.14.4-1. De communicatie met de machine vond plaats via SSH.

Poging # 1 eenvoudige oplossing

Een paar woorden over de huidige: de variabele stroom verwijst naar een task_struct-structuur met een beschrijving van het proces in de kernel (PID, UID, GID, cmdline, naamruimten, enz.)

Het eerste idee was om eenvoudig de parameter current-> pid van de kernelmodule in de gewenste te veranderen.

Statische ssize_t device_read (struct-bestand * filp, char * buffer, size_t length, loff_t * offset) (printk ("PID:% d. \ N", huidig-> pid); huidig-> pid = 1; printk ("nieuw PID:% d. \ N ", stroom-> pid);,)
Om de functionaliteit van de module te testen heb ik een programma geschreven in C++:

#erbij betrekken #erbij betrekken #erbij betrekken int main () (std :: cout<< "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >> str; standaard :: cout<< "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
Laad de module met het commando insmod, maak / dev / test en probeer het.

# ./a.out Mijn ouder PID 293 Mijn PID 782 Mijn nieuwe PID 782
De PID is niet gewijzigd. Dit is misschien niet de enige plaats waar de PID wordt vermeld.

Poging # 2 extra PID-velden

Als current-> pid niet de proces-ID is, wat dan wel? Een snelle blik op de getpid ()-code wees naar de task_struct-structuur die het Linux-proces en het pid.c-bestand in de kernelbron beschrijft. De vereiste functie is __task_pid_nr_ns. De functiecode bevat de aanroeptaak-> pids.pid, we zullen deze parameter wijzigen

Compileren, proberen

Omdat ik via SSH heb getest, kon ik de uitvoer van het programma krijgen voordat de kernel crashte:

Mijn ouder PID 293 Mijn PID 1689 Mijn nieuwe PID 1689
Het eerste resultaat is al iets. Maar de PID is nog steeds niet veranderd.

Poging #3 niet-geëxporteerde kernelsymbolen

Een nadere blik op pid.c leverde een functie op die doet wat we nodig hebben
statische leegte __change_pid (struct task_struct * taak, enum pid_type type,
struct pid * nieuw)
De functie accepteert een taak waarvoor het nodig is om de PID, het PID-type en in feite de nieuwe PID te wijzigen. De nieuwe PID wordt gemaakt door de functie
struct pid * alloc_pid (struct pid_namespace * ns)

Deze functie accepteert alleen de naamruimte waarin de nieuwe PID zich bevindt, deze ruimte kan worden verkregen met task_active_pid_ns.
Maar er is één probleem: deze kernelsymbolen worden niet door de kernel geëxporteerd en kunnen niet in modules worden gebruikt. Bij het oplossen van dit probleem heeft een geweldige me geholpen. De functiecode find_sym wordt daar vandaan gehaald.

Statische asmlinkage void (* change_pidR) (struct task_struct * task, enum pid_type type, struct pid * pid); statische asmlinkage struct pid * (* alloc_pidR) (struct pid_namespace * ns); static int __init test_init (void) (printk (KERN_ALERT "TEST-stuurprogramma geladen! \ n"); change_pidR = find_sym ("change_pid"); alloc_pidR = find_sym ("alloc_pid"); ...) static ssize_t device_read (structbestand * filp, char * buffer, size_t length, loff_t * offset) (printk ("PID:% d. \ n", current-> pid); struct pid * newpid; newpid = alloc_pidR (task_active_pid_ns (huidig)); change_pidR (huidig , PIDTYPE_PID, newpid); printk ("nieuwe PID:% d. \ N", huidig-> pid); ...)
Compliment, lancering

Mijn ouder PID 299 Mijn PID 750 Mijn nieuwe PID 751
PID gewijzigd! De kernel heeft automatisch een gratis PID aan ons programma toegewezen. Maar is het mogelijk om een ​​PID te gebruiken die een ander proces heeft overgenomen, zoals PID 1? Code toevoegen na toewijzing

Newpid-> getallen.nr = 1;
Compliment, lancering

Mijn ouder PID 314 Mijn PID 1172 Mijn nieuwe PID 1
We krijgen de echte PID 1!

Bash gaf een foutmelding waarbij het inschakelen van opdracht% n niet werkt, maar alle andere functies werken prima.

Interessante kenmerken van processen met gewijzigde PID

PID 0: enter kan niet uitgelogd worden

Laten we teruggaan naar de code en de PID wijzigen in 0.

Newpid-> getallen.nr = 0;
Compliment, lancering

Mijn ouder PID284 Mijn PID 1517 Mijn nieuwe PID 0
Dus PID 0 is niet zo bijzonder? We zijn blij, schrijven exit en ...

De kern valt! De kernel definieerde onze taak als IDLE TASK en toen het voltooid was, crashte het gewoon. Blijkbaar zou ons programma, vóór beëindiging, naar zichzelf de "normale" PID moeten teruggeven.

Het onzichtbare proces

Laten we teruggaan naar de code en de PID instellen, die gegarandeerd onbezet is
nieuwepid-> nummers.nr = 12345;

Compliment, lancering

Mijn ouder PID296 Mijn PID 735 Mijn nieuwe PID 12345
Laten we eens kijken wat er in zit / proc

1 148 19 224 288 37 79 86 93 consoles fb kcore sloten partities swaps versie 10 149 2 226 29 4 8 87 acpi cpuinfo bestandssystemen key-users meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs-sleutels misc schedstat sysrq- trigger vmstat 11 16 208 24 291 6 81 89 buddyinfo devices interrupts kmsg modules scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup mounts self thread-self 13 176 210 26 3 737 83 90 cgroups dma ioports kpagecount mtrr slabinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg pagetypeinfo stat uptime
Zoals je kunt zien definieert / proc ons proces niet, zelfs niet als we een gratis PID hebben geleend. De vorige PID zit ook niet in / proc, wat erg vreemd is. Het kan zijn dat we in een andere naamruimte zitten en daarom niet zichtbaar zijn voor de main / proc. Laten we een nieuwe / proc koppelen en kijken wat daar in zit

1 14 18 210 25 291 738 81 9 busapparaten fs key-users vergrendelingen paginatypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrupts sleutels meminfo partities stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg misc sched_debug wisselt uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys versie 12 16 20 226 288 4 79 85 acpi consoles execdomains irq kpagecount mounts scsi sysrq-trigger vmallocinfo 13 17 86 als 23 29 6 8 cpuinfo fb ​​​​kallsyms kpageflags mtrr zelf sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto bestandssystemen kcore loadavg net slabinfo thread-self zoneinfo
Zoals eerder is ons proces er niet, wat betekent dat we ons in een reguliere naamruimte bevinden. Laten we het controleren

Ps -e | grep bash
296 punten / 0 00:00:00 bash

Slechts één bash, van waaruit we het programma draaiden. Noch de vorige PID, noch de huidige staat in de lijst.

In dit artikel zullen we proberen een kernelmodule te maken die de PID van een al actief proces in Linux kan wijzigen, en ook experimenteren met processen die een gewijzigde PID hebben ontvangen.


Een waarschuwing: Het wijzigen van de PID is een niet-standaard proces en kan onder bepaalde omstandigheden leiden tot kernel panic.

Onze testeenheid zal het karakterapparaat / dev / test implementeren, wat de PID van het proces zal veranderen wanneer het wordt gelezen. Voor een voorbeeld van de implementatie van een karakterapparaat, dankzij dit artikel. De volledige modulecode staat aan het einde van het artikel. De meest correcte oplossing was natuurlijk om een ​​systeemaanroep aan de kernel zelf toe te voegen, maar hiervoor zou de kernel opnieuw moeten worden gecompileerd.

Omgeving

Alle stappen voor het testen van de module zijn uitgevoerd in een VirtualBox virtuele machine met een 64-bit Linux-distributie en kernelversie 4.14.4-1. De communicatie met de machine vond plaats via SSH.

Poging # 1 eenvoudige oplossing

Een paar woorden over de huidige: de variabele stroom verwijst naar een task_struct-structuur met een beschrijving van het proces in de kernel (PID, UID, GID, cmdline, naamruimten, enz.)

Het eerste idee was om eenvoudig de parameter current-> pid van de kernelmodule in de gewenste te veranderen.

Statische ssize_t device_read (struct-bestand * filp, char * buffer, size_t length, loff_t * offset) (printk ("PID:% d. \ N", huidig-> pid); huidig-> pid = 1; printk ("nieuw PID:% d. \ N ", stroom-> pid);,)
Om de functionaliteit van de module te testen heb ik een programma geschreven in C++:

#erbij betrekken #erbij betrekken #erbij betrekken int main () (std :: cout<< "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >> str; standaard :: cout<< "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
Laad de module met het commando insmod, maak / dev / test en probeer het.

# ./a.out Mijn ouder PID 293 Mijn PID 782 Mijn nieuwe PID 782
De PID is niet gewijzigd. Dit is misschien niet de enige plaats waar de PID wordt vermeld.

Poging # 2 extra PID-velden

Als current-> pid niet de proces-ID is, wat dan wel? Een snelle blik op de getpid ()-code wees naar de task_struct-structuur die het Linux-proces en het pid.c-bestand in de kernelbron beschrijft. De vereiste functie is __task_pid_nr_ns. De functiecode bevat de aanroeptaak-> pids.pid, we zullen deze parameter wijzigen

Compileren, proberen

Omdat ik via SSH heb getest, kon ik de uitvoer van het programma krijgen voordat de kernel crashte:

Mijn ouder PID 293 Mijn PID 1689 Mijn nieuwe PID 1689
Het eerste resultaat is al iets. Maar de PID is nog steeds niet veranderd.

Poging #3 niet-geëxporteerde kernelsymbolen

Een nadere blik op pid.c leverde een functie op die doet wat we nodig hebben
statische leegte __change_pid (struct task_struct * taak, enum pid_type type,
struct pid * nieuw)
De functie accepteert een taak waarvoor het nodig is om de PID, het PID-type en in feite de nieuwe PID te wijzigen. De nieuwe PID wordt gemaakt door de functie
struct pid * alloc_pid (struct pid_namespace * ns)

Deze functie accepteert alleen de naamruimte waarin de nieuwe PID zich bevindt, deze ruimte kan worden verkregen met task_active_pid_ns.
Maar er is één probleem: deze kernelsymbolen worden niet door de kernel geëxporteerd en kunnen niet in modules worden gebruikt. Bij het oplossen van dit probleem heeft een geweldige me geholpen. De functiecode find_sym wordt daar vandaan gehaald.

Statische asmlinkage void (* change_pidR) (struct task_struct * task, enum pid_type type, struct pid * pid); statische asmlinkage struct pid * (* alloc_pidR) (struct pid_namespace * ns); static int __init test_init (void) (printk (KERN_ALERT "TEST-stuurprogramma geladen! \ n"); change_pidR = find_sym ("change_pid"); alloc_pidR = find_sym ("alloc_pid"); ...) static ssize_t device_read (structbestand * filp, char * buffer, size_t length, loff_t * offset) (printk ("PID:% d. \ n", current-> pid); struct pid * newpid; newpid = alloc_pidR (task_active_pid_ns (huidig)); change_pidR (huidig , PIDTYPE_PID, newpid); printk ("nieuwe PID:% d. \ N", huidig-> pid); ...)
Compliment, lancering

Mijn ouder PID 299 Mijn PID 750 Mijn nieuwe PID 751
PID gewijzigd! De kernel heeft automatisch een gratis PID aan ons programma toegewezen. Maar is het mogelijk om een ​​PID te gebruiken die een ander proces heeft overgenomen, zoals PID 1? Code toevoegen na toewijzing

Newpid-> getallen.nr = 1;
Compliment, lancering

Mijn ouder PID 314 Mijn PID 1172 Mijn nieuwe PID 1
We krijgen de echte PID 1!

Bash gaf een foutmelding waarbij het inschakelen van opdracht% n niet werkt, maar alle andere functies werken prima.

Interessante kenmerken van processen met gewijzigde PID

PID 0: enter kan niet uitgelogd worden

Laten we teruggaan naar de code en de PID wijzigen in 0.

Newpid-> getallen.nr = 0;
Compliment, lancering

Mijn ouder PID284 Mijn PID 1517 Mijn nieuwe PID 0
Dus PID 0 is niet zo bijzonder? We zijn blij, schrijven exit en ...

De kern valt! De kernel definieerde onze taak als IDLE TASK en toen het voltooid was, crashte het gewoon. Blijkbaar zou ons programma, vóór beëindiging, naar zichzelf de "normale" PID moeten teruggeven.

Het onzichtbare proces

Laten we teruggaan naar de code en de PID instellen, die gegarandeerd onbezet is
nieuwepid-> nummers.nr = 12345;

Compliment, lancering

Mijn ouder PID296 Mijn PID 735 Mijn nieuwe PID 12345
Laten we eens kijken wat er in zit / proc

1 148 19 224 288 37 79 86 93 consoles fb kcore sloten partities swaps versie 10 149 2 226 29 4 8 87 acpi cpuinfo bestandssystemen key-users meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs-sleutels misc schedstat sysrq- trigger vmstat 11 16 208 24 291 6 81 89 buddyinfo devices interrupts kmsg modules scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup mounts self thread-self 13 176 210 26 3 737 83 90 cgroups dma ioports kpagecount mtrr slabinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg pagetypeinfo stat uptime
Zoals je kunt zien definieert / proc ons proces niet, zelfs niet als we een gratis PID hebben geleend. De vorige PID zit ook niet in / proc, wat erg vreemd is. Het kan zijn dat we in een andere naamruimte zitten en daarom niet zichtbaar zijn voor de main / proc. Laten we een nieuwe / proc koppelen en kijken wat daar in zit

1 14 18 210 25 291 738 81 9 busapparaten fs key-users vergrendelingen paginatypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrupts sleutels meminfo partities stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg misc sched_debug wisselt uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys versie 12 16 20 226 288 4 79 85 acpi consoles execdomains irq kpagecount mounts scsi sysrq-trigger vmallocinfo 13 17 86 als 23 29 6 8 cpuinfo fb ​​​​kallsyms kpageflags mtrr zelf sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto bestandssystemen kcore loadavg net slabinfo thread-self zoneinfo
Zoals eerder is ons proces er niet, wat betekent dat we ons in een reguliere naamruimte bevinden. Laten we het controleren

Ps -e | grep bash
296 punten / 0 00:00:00 bash

Slechts één bash, van waaruit we het programma draaiden. Noch de vorige PID, noch de huidige staat in de lijst.

Elk nieuw proces dat door de kernel wordt gecreëerd, krijgt een uniek identificatienummer (PID) toegewezen. Net als een sofi-kaartnummer maakt de werkelijke PID-waarde niet veel uit. Procesidentificatienummers worden op volgorde toegewezen, beginnend bij nul. Wanneer de kernel geen nummers meer heeft, keert hij weer terug naar nul en wijst ze opnieuw in volgorde toe, waarbij de PID's die nog in gebruik zijn worden overgeslagen.

Bovenliggende proces-ID (ppid)

In UNIX is er geen systeemaanroep die een nieuw proces zou creëren om een ​​specifiek programma uit te voeren. Een nieuw proces wordt gemaakt door een van de bestaande processen te klonen, waarna de tekst van de kloon wordt vervangen door de tekst van het programma dat het proces moet uitvoeren.

Het oorspronkelijke proces in UNIX-terminologie wordt de ouder genoemd en de kloon ervan wordt het kind genoemd. Naast zijn eigen identifier heeft elk proces een PPID-attribuut, d.w.z. de identifier van het bovenliggende proces.

Gebruikers-ID (uid) en effectief gebruikers-ID (euid)

De UID is het identificatienummer van de gebruiker die dit proces heeft gemaakt. Alleen de maker en de bevoorrechte gebruiker kunnen wijzigingen aanbrengen in een proces. Het boekhoudsysteem wijst aan de maker van het proces alle middelen toe die zijn proces gebruikt.

De EUID is de "effectieve" UID van het proces. De EUID wordt gebruikt om te bepalen tot welke bronnen en bestanden een proces toegang heeft. De meeste processen hebben dezelfde UID en EUID. De enige uitzonderingen zijn programma's die de gebruikers-ID-wijzigingsbit hebben ingesteld (zie over SUID in de sectie over het instellen van toegangsrechten tot bestanden en mappen).

Groeps-ID (gid) en effectieve groeps-ID (egid)

GID is het groepsidentificatienummer van dit proces. Geldige groeps-ID's worden gespecificeerd in het bestand / enzovoort/ groep en in het GID-veld van het bestand / etc/ passwd. Wanneer een proces start, wordt de GID ingesteld op de GID van het bovenliggende proces.

EGID is op dezelfde manier gekoppeld aan GID als EUID met UID. Als een proces toegang probeert te krijgen tot een bestand waarvan het geen eigendom heeft, zal de kernel automatisch controleren of het toestemming kan verlenen op basis van de gegeven EEGID.

Op sommige systemen kan een proces tegelijkertijd tot meerdere groepen behoren. In dit geval is EGID gewoon een lijst met groeps-ID's. Als een gebruiker toegang probeert te krijgen tot een bron, wordt de hele lijst gecontroleerd om te zien of de gebruiker tot een groep behoort waarvan de leden de bron mogen gebruiken.

Prioriteit en waarde leuk

De prioriteit van het proces bepaalt hoeveel CPU-tijd het krijgt. Bij het kiezen van een proces om uit te voeren, vindt de kernel het proces met de hoogste "interne prioriteit".

Je kunt de interne prioriteit niet direct instellen, maar wel de zogenaamde nice-waarde, die de interne prioriteit aanzienlijk beïnvloedt. Bovendien hangt de interne prioriteit af van hoeveel CPU-tijd het proces al heeft gebruikt en hoe lang het wacht op zijn eigen uitvoeringswachtrij.

Proces levenscyclus

Processen verschijnen niet op magische wijze in het systeem en worden niet spontaan gecreëerd door de kernel. Nieuwe processen worden gegenereerd door andere processen, net als mensen.

Om een ​​nieuw proces aan te maken, kopieert een bestaand proces zichzelf met behulp van de fork-systeemaanroep. Calling fork maakt een kopie van het oorspronkelijke proces dat identiek is aan het bovenliggende proces, maar met de volgende verschillen:

    het nieuwe proces heeft zijn eigen PID;

    De PPID van het nieuwe proces is gelijk aan de PID van de ouder;

    de boekhoudkundige informatie van het nieuwe proces is gewist;

    het nieuwe proces heeft zijn eigen instantie van bestandsdescriptors.

Wanneer het systeem opstart, maakt de kernel zelf verschillende processen aan. De belangrijkste hiervan is het proces (daemon) in het Wiens PID altijd 1 is. Dit proces is verantwoordelijk voor het aanroepen van shell om opstartscripts uit te voeren rc, als uw systeem ze gebruikt. Alle andere processen dan die gemaakt door de kernel zijn afstammelingen in het.

Na het verwerken van de opstartbestanden, wordt het proces in het start een proces voor elke virtuele terminal getty.

Proces in het speelt een belangrijke rol bij procesbeheersing. Wanneer het proces is voltooid, roept het de subroutine _ Uitgang om de kernel te informeren dat het klaar is om te sterven. Als een parameter voor een subroutine _ Uitgang verzonden voltooiingscode - een geheel getal dat de reden voor de beëindiging van het proces aangeeft. Volgens afspraak betekent een nul-exitcode dat het proces "succesvol" was.

De afsluitcode is vereist door het bovenliggende proces, dus de kernel moet deze bewaren totdat het bovenliggende proces hierom vraagt ​​met een systeemaanroep wacht... Het feit is dat wanneer een proces eindigt, zijn adresruimte wordt vrijgemaakt, er geen CPU-tijd aan dit proces wordt toegewezen, maar een record erover wordt opgeslagen in de kernelprocestabel. Het proces in deze staat wordt "zombie" genoemd.

Dit mechanisme werkt prima als het bovenliggende proces later wordt afgesloten dan de processen die het voortbrengt en te goeder trouw aanroept wacht om alle processen - zombies te laten sterven. Als het bovenliggende proces eerst sterft, dan begrijpt de kernel dat de aanroep wacht zal niet volgen, en geeft alle zombies aan het proces in het... Proces in het moet deze "verweesde" zombies accepteren en de uitdaging voltooien wacht nodig om ze te elimineren. Soms in het voert zijn taken niet goed uit en de zombies blijven in het systeem. Maar ze veroorzaken tegelijkertijd geen problemen.