Čitatelji poput vas podržavaju MUO. Kada kupite putem poveznica na našoj stranici, možemo zaraditi partnersku proviziju. Čitaj više.

Na Linuxu možete stvarati niti upravljati njima u C/C++ koristeći biblioteku POSIX niti (pthread). Za razliku od drugih operativnih sustava, u Linuxu postoji mala razlika između niti i procesa. Zato Linux svoje niti često naziva lakim procesima.

Koristeći biblioteku pthread, možete kreirati niti, čekati da završe i eksplicitno ih prekinuti.

Povijest korištenja niti na Linuxu

Prije verzije Linuxa 2.6, implementacija glavne niti bila je LinuxThreads. Ova implementacija je imala značajna ograničenja u pogledu performansi i operacija sinkronizacije. Ograničenje maksimalnog broja niti koje se mogu izvoditi ograničilo ih je na 1000.

Godine 2003. tim predvođen programerima iz IBM-a i RedHata uspio je napraviti Izvorna knjižnica niti POSIX (NPTL) projekt dostupan. Prvi put je predstavljen u RedHat Enterprise verziji 3 za rješavanje problema s performansama s Java Virtual Machine na Linuxu. Danas GNU C biblioteka sadrži implementacije oba mehanizma niti.

instagram viewer

Nijedno od ovoga nije implementacija zelenih niti, kojima bi Virtualni stroj upravljao i izvodio ih u čisto korisničkom načinu rada. Kada koristite biblioteku pthread, kernel stvara nit svaki put kada se program pokrene.

Možete pronaći informacije specifične za niti za bilo koji pokrenuti proces u datotekama ispod /proc//task. Ovo je standardno mjesto za informacije o procesu ispod procfs Linux standard. Za aplikacije s jednom niti, činit će se da postoji zapis zadatka s istom vrijednošću kao PID u ovom direktoriju.

Logika rada niti

Niti su poput procesa koji se trenutno izvode na operativnom sustavu. U jednoprocesorskim sustavima (npr. mikrokontroleri), jezgra operacijskog sustava simulira niti. To omogućuje da se transakcije izvode istovremeno kroz rezanje.

Operativni sustav s jednom jezgrom zaista može pokrenuti samo jedan proces u isto vrijeme. Međutim, u višejezgreni ili višeprocesorski sustavi, ti se procesi mogu odvijati istovremeno.

Stvaranje niti u C

Možete koristiti pthread_create funkciju za stvaranje nove niti. The pnit.h datoteka zaglavlja uključuje svoju definiciju potpisa zajedno s drugim funkcijama povezanim s nitima. Niti koriste isti adresni prostor i deskriptore datoteka kao i glavni program.

Knjižnica pthread također uključuje potrebnu podršku za mutex i uvjetne operacije potrebne za operacije sinkronizacije.

Kada koristite funkcije biblioteke pthread, morate osigurati da kompajler povezuje pnit knjižnicu u vašu izvršnu datoteku. Ako je potrebno, možete uputiti kompilator da se poveže s bibliotekom pomoću -l opcija:

gcc -o test ispitna_nit.c -lpnit

Funkcija pthread_create ima sljedeći potpis:

intpthread_create(pnit_t *nit, konstpthread_attr_t *attr, poništiti *(*start_routine)(poništiti *), poništiti *arg)

Vraća 0 ako je postupak uspješan. Ako postoji problem, vraća kôd pogreške različit od nule. U gornjem potpisu funkcije:

  • The nit parametar je tipa pnit_t. Stvorena nit će uvijek biti dostupna s ovom referencom.
  • The attr parametar vam omogućuje da odredite prilagođeno ponašanje. Možete koristiti niz funkcija specifičnih za niti počevši od pthread_attr_ za postavljanje ove vrijednosti. Moguće prilagodbe su politika raspoređivanja, veličina hrpe i politika odvajanja.
  • početak_rutine specificira funkciju koju će nit izvoditi.
  • arg predstavlja strukturu generičkih podataka koju nit prosljeđuje funkciji.

Evo primjera aplikacije:

#uključiti
#uključiti
#uključiti
#uključiti

poništiti *radnik(poništiti *podaci)
{
char *ime = (char*)podaci;

za (int ja = 0; ja < 120; i++)
{
spavati(50000);
printf("Pozdrav iz imena niti = %s\n", ime);
}

printf("Nit %s gotova!\n", naziv);
povratakNULL;
}

intglavni(poništiti)
{
pnit_t th1, th2;
pthread_create(&th1, NULL, radnik, "X");
pthread_create(&th2, NULL, radnik, "Y");
spavati(5);
printf("Izlaz iz glavnog programa\n");
povratak0;
}

Vrste niti

Kada se nit vrati iz glavni() funkcija u aplikaciji, sve niti završavaju i sustav oslobađa sve resurse koje je program koristio. Isto tako, kada izlazite iz bilo koje niti s naredbom poput an Izlaz(), vaš program će prekinuti sve niti.

s pthread_join umjesto toga možete pričekati da nit završi. Nit koja koristi ovu funkciju blokirat će se dok očekivana nit ne završi. Resursi koje koriste iz sustava ne vraćaju se čak ni u slučajevima kao što su prekid niti koje se mogu pridružiti, neplanirano od strane CPU-a ili čak neuspjeh spajanja s ptread_join.

Ponekad postoje situacije u kojima spajanje s pthread_join nema smisla; ako je nemoguće predvidjeti kada će nit završiti, na primjer. U tom slučaju možete osigurati da sustav automatski vraća sve resurse na mjestu gdje se nit vraća.

Da biste to postigli, trebali biste pokrenuti relevantne niti s ODVOJENA status. Prilikom pokretanja niti, ODVOJITI status se može postaviti preko vrijednosti atributa niti ili pomoću pthread_detach funkcija:

intpthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
intpthread_detach(pnit_t nit);

Evo primjera upotrebe pthread_join(). Zamijenite glavnu funkciju u prvom programu sa sljedećim:

intglavni(poništiti)
{
pnit_t th1, th2;
pthread_create(&th1, NULL, radnik, "X");
pthread_create(&th2, NULL, radnik, "Y");
spavati(5);
printf("izlazak iz glavnog programa\n");
pthread_join (th1, NULL);
pthread_join (th2, NULL);
povratak0;
}

Kada prevedete i pokrenete program, vaš izlaz će biti:

Pozdrav iz teme Y
Pozdrav iz teme X
Pozdrav iz teme Y
...
Pozdrav iz teme Y
izlaz iz glavnog programa
Pozdrav iz teme X
...
Pozdrav iz teme X
Nit X gotova!
Pozdrav iz teme Y
Nit Y gotov!

Završetak niti

Nit možete otkazati pozivom pthread_cancel prosljeđivanjem odgovarajućeg pnit_t iskaznica:

intpthread_cancel(pnit_t nit);

To možete vidjeti na djelu u sljedećem kodu. Opet, samo glavni funkcija je drugačija:

intglavni(poništiti)
{
pnit_t th1, th2;
pthread_create(&th1, NULL, radnik, "X");
pthread_create(&th2, NULL, radnik, "Y");
spavati(1);
printf("> Otkazivanje niti Y!!\n");
pthread_cancel (th2);
spavati(100000);
printf("> Otkazivanje niti X!\n");
pnit_otkaži (th1);
printf("izlazak iz glavnog programa\n");
povratak0;
}

Zašto se stvaraju niti?

Operativni sustavi uvijek pokušavaju pokrenuti niti na jednom ili više CPU-a, bilo s popisa koji su sami kreirali ili s popisa niti koji je stvorio korisnik. Neke se niti ne mogu pokrenuti jer čekaju ulazni/izlazni signal od hardvera. Oni također mogu dobrovoljno čekati, čekati odgovor od druge niti ili ih druga nit blokira.

Možete podesiti resurse koje dodjeljujete nitima koje stvarate koristeći pthread. To može biti prilagođena politika zakazivanja ili možete odabrati algoritme za zakazivanje kao što su FIFO ili Round-robin ako želite.