V sistemu Linux lahko ustvarjate in upravljate niti v C/C++ s knjižnico niti POSIX (pthread). Za razliko od drugih operacijskih sistemov je v Linuxu majhna razlika med nitjo in procesom. Zato Linux svoje niti pogosto imenuje lahki procesi.
Z uporabo knjižnice pthread lahko ustvarite niti, počakate, da se zaključijo, in jih izrecno prekinete.
Zgodovina uporabe niti v sistemu Linux
Pred različico Linuxa 2.6 je bila implementacija glavne niti LinuxThreads. Ta izvedba je imela precejšnje omejitve glede zmogljivosti in sinhronizacijskih operacij. Omejitev največjega števila niti, ki se lahko izvajajo, jih je omejila na 1000-ih.
Leta 2003 je ekipi pod vodstvom razvijalcev iz IBM-a in RedHata uspelo izdelati Izvorna knjižnica niti POSIX (NPTL) projekt na voljo. Prvič je bil predstavljen v RedHat Enterprise različici 3 za reševanje težav z zmogljivostjo Java Virtual Machine v Linuxu. Danes knjižnica GNU C vsebuje izvedbe obeh mehanizmov niti.
Nobeden od teh ni izvedba zelenih niti, ki bi jih virtualni stroj upravljal in izvajal v izključno uporabniškem načinu. Ko uporabljate knjižnico pthread, jedro ustvari nit ob vsakem zagonu programa.
Podatke, specifične za nit, za kateri koli tekoči proces najdete v spodnjih datotekah /proc/
Delovna logika niti
Niti so kot procesi, ki se trenutno izvajajo v operacijskem sistemu. V enoprocesorskih sistemih (npr. mikrokontrolerjih) jedro operacijskega sistema simulira niti. To omogoča sočasno izvajanje transakcij skozi rezanje.
Enojedrni operacijski sistem lahko resnično izvaja samo en proces naenkrat. Vendar pa v večjedrni ali večprocesorski sistemi, lahko ti procesi tečejo hkrati.
Ustvarjanje niti v C
Lahko uporabite pthread_create funkcijo za ustvarjanje nove niti. The pthread.h glava vključuje svojo definicijo podpisa skupaj z drugimi funkcijami, povezanimi z nitjo. Niti uporabljajo isti naslovni prostor in deskriptorje datotek kot glavni program.
Knjižnica pthread vključuje tudi potrebno podporo za mutex in pogojne operacije, potrebne za sinhronizacijske operacije.
Ko uporabljate funkcije knjižnice pthread, morate zagotoviti, da prevajalnik povezuje pthread knjižnico v vašo izvršljivo datoteko. Po potrebi lahko prevajalniku naročite, da se poveže s knjižnico z uporabo -l možnost:
gcc -o test testna_nit.c -lpnit
Funkcija pthread_create ima naslednji podpis:
intpthread_create(pthread_t *nit, konstpthread_attr_t *attr, praznina *(*start_routine)(praznina *), praznina *arg)
Če je postopek uspešen, vrne 0. Če pride do težave, vrne kodo napake, ki ni nič. V zgornjem podpisu funkcije:
- The nit parameter je vrste pthread_t. Ustvarjena nit bo vedno dostopna s to referenco.
- The attr parameter vam omogoča, da določite vedenje po meri. Uporabite lahko niz funkcij, specifičnih za nit, ki se začnejo z pthread_attr_ da nastavite to vrednost. Možne prilagoditve so politika razporejanja, velikost sklada in politika odklopa.
- start_rutine določa funkcijo, ki jo bo izvajala nit.
- arg predstavlja generično podatkovno strukturo, ki jo nit posreduje funkciji.
Tukaj je primer aplikacije:
#vključujejo
#vključujejo
#vključujejo
#vključujejopraznina *delavec(praznina *podatki)
{
char *ime = (char*)podatki;
za (int jaz = 0; jaz < 120; i++)
{
spi(50000);
printf("Pozdravljeni iz imena niti = %s\n", ime);
}
printf("Nit %s končana!\n", ime);
vrnitevNIČ;
}
intglavni(praznina)
{
pthread_t th1, th2;
pthread_create(&th1, NIČ, delavec, "X");
pthread_create(&th2, NIČ, delavec, "Y");
spati(5);
printf("Izhod iz glavnega programa\n");
vrnitev0;
}
Vrste niti
Ko se nit vrne iz glavni () delovanje v aplikaciji, se vse niti končajo in sistem sprosti vse vire, ki jih je program uporabljal. Podobno, ko zapustite katero koli nit z ukazom, kot je an izhod(), bo vaš program prekinil vse niti.
z pthread_join namesto tega lahko počakate, da se nit zaključi. Nit, ki uporablja to funkcijo, bo blokirana, dokler se pričakovana nit ne prekine. Viri, ki jih uporabljajo iz sistema, se ne vrnejo niti v primerih, kot je prekinitev združljivih niti, ki jih ne načrtuje CPE, ali celo neuspešna povezava ptread_join.
Včasih obstajajo situacije, ko združevanje s pthread_join ni smiselno; če je na primer nemogoče predvideti, kdaj se bo nit končala. V tem primeru lahko zagotovite, da sistem samodejno vrne vse vire na točki, kjer se vrne nit.
Če želite to doseči, bi morali začeti ustrezne niti z ODSTOJENO stanje. Ko začnete nit, ODKLOPITE status lahko nastavite prek vrednosti atributa niti ali z pthread_detach funkcija:
intpthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
intpthread_detach(pthread_t nit);
Tukaj je primer uporabe pthread_join(). Zamenjajte glavno funkcijo v prvem programu z naslednjim:
intglavni(praznina)
{
pthread_t th1, th2;
pthread_create(&th1, NIČ, delavec, "X");
pthread_create(&th2, NIČ, delavec, "Y");
spati(5);
printf("izhod iz glavnega programa\n");
pthread_join (th1, NIČ);
pthread_join (th2, NIČ);
vrnitev0;
}
Ko prevedete in zaženete program, bo vaš rezultat:
Živjo iz niti Y
Živjo iz teme X
Živjo iz niti Y
...
Živjo iz niti Y
izhod iz glavnega programa
Živjo iz teme X
...
Živjo iz teme X
Nit X končana!
Živjo iz niti Y
Nit Y končana!
Prekinitev niti
Nit lahko prekličete s klicem pthread_cancel, ki posreduje ustrezen pthread_t id:
intpthread_cancel(pthread_t nit);
To lahko vidite v akciji v naslednji kodi. Še enkrat, samo glavni funkcija je drugačna:
intglavni(praznina)
{
pthread_t th1, th2;
pthread_create(&th1, NIČ, delavec, "X");
pthread_create(&th2, NIČ, delavec, "Y");
spati(1);
printf("> Preklic niti Y!!\n");
pthread_cancel (th2);
spi(100000);
printf("> Preklic niti X!\n");
pthread_cancel (th1);
printf("izhod iz glavnega programa\n");
vrnitev0;
}
Zakaj so niti ustvarjene?
Operacijski sistemi vedno poskušajo zagnati niti na enem ali več procesorjih, bodisi s seznama, ki ga ustvarijo sami, ali s seznama niti, ki ga ustvari uporabnik. Nekatere niti se ne morejo izvajati, ker čakajo na vhodno/izhodni signal iz strojne opreme. Morda tudi prostovoljno čakajo, čakajo na odgovor druge niti ali pa jih druga nit blokira.
Prilagodite lahko vire, ki jih dodelite nitim, ki jih ustvarite s pthread. To je lahko pravilnik o razporejanju po meri ali pa po želji izberete algoritme za razporejanje, kot sta FIFO ali Round-robin.