„Linux“ sistemoje galite kurti ir valdyti C/C++ gijas naudodami POSIX gijų (pthread) biblioteką. Skirtingai nuo kitų operacinių sistemų, „Linux“ sistemoje yra mažai skirtumų tarp gijos ir proceso. Štai kodėl „Linux“ savo gijas dažnai vadina lengvais procesais.
Naudodami pthread biblioteką galite sukurti gijas, palaukti, kol jos pasibaigs, ir aiškiai jas nutraukti.
„Linux“ gijų naudojimo istorija
Prieš Linux 2.6 versiją pagrindinė gijos diegimas buvo LinuxThreads. Šis diegimas turėjo didelių našumo ir sinchronizavimo operacijų apribojimų. Dėl didžiausio galimų paleisti gijų skaičiaus apribojimas buvo apribotas iki 1000 s.
2003 m. IBM ir RedHat kūrėjų vadovaujamai komandai pavyko sukurti Vietinė POSIX gijų biblioteka (NPTL) projektas. Pirmą kartą jis buvo pristatytas RedHat Enterprise 3 versijoje, siekiant išspręsti „Java“ virtualiosios mašinos našumo problemas „Linux“. Šiandien GNU C bibliotekoje yra abiejų sriegimo mechanizmų įgyvendinimai.
Nė vienas iš jų nėra žaliųjų gijų, kurias virtualioji mašina valdytų ir veiktų tik vartotojo režimu, įgyvendinimas. Kai naudojate pthread biblioteką, branduolys sukuria giją kiekvieną kartą, kai programa paleidžiama.
Konkrečios gijos informacijos apie bet kurį vykdomą procesą galite rasti toliau pateiktuose failuose /proc/
Siūlų darbo logika
Gijos yra kaip procesai, šiuo metu veikiantys operacinėje sistemoje. Vieno procesoriaus sistemose (pvz., mikrovaldikliuose) operacinės sistemos branduolys imituoja gijas. Tai leidžia operacijas vykdyti vienu metu per pjaustymą.
Vieno branduolio operacinė sistema vienu metu gali vykdyti tik vieną procesą. Tačiau į kelių branduolių arba kelių procesorių sistemos, šie procesai gali vykti vienu metu.
Gijos kūrimas C
Galite naudoti pthread_create funkcija sukurti naują giją. The pthread.h antraštės failas apima jo parašo apibrėžimą kartu su kitomis su gijomis susijusiomis funkcijomis. Gijos naudoja tą pačią adresų erdvę ir failų aprašus kaip ir pagrindinė programa.
Pthread biblioteka taip pat apima būtiną palaikymą mutex ir sąlyginėms operacijoms, reikalingoms sinchronizavimo operacijoms.
Kai naudojate pthread bibliotekos funkcijas, turite užtikrinti, kad kompiliatorius susietų su p gijos biblioteką į vykdomąjį failą. Jei reikia, galite nurodyti kompiliatoriui susieti su biblioteka naudodami -l variantas:
gcc -o bandymas test_thread.c -lpthread
Funkcija pthread_create turi tokį parašą:
tarptpthread_create(pthread_t *siūlas, konstpthread_attr_t *attr, tuštuma **(*pradėti_rutina)(tuštuma *), tuštuma *arg)
Jei procedūra sėkminga, ji grąžina 0. Jei kyla problemų, jis grąžina klaidos kodą, kuris nėra nulis. Aukščiau pateiktoje funkcijos paraše:
- The siūlas parametras yra tipo pthread_t. Sukurta gija visada bus pasiekiama naudojant šią nuorodą.
- The attr parametras leidžia nurodyti pasirinktinį elgesį. Galite naudoti daugybę specifinių gijų funkcijų, pradedant nuo pthread_attr_ norėdami nustatyti šią vertę. Galimi tinkinimai yra planavimo politika, dėklo dydis ir atskyrimo politika.
- start_rutina nurodo funkciją, kurią gija vykdys.
- arg reiškia bendrąją duomenų struktūrą, kurią funkcijai perduoda gija.
Štai programos pavyzdys:
#įtraukti
#įtraukti
#įtraukti
#įtrauktituštuma *darbininkas(tuštuma *duomenys)
{
char *vardas = (char*)duomenys;
dėl (tarpt aš = 0; aš < 120; aš++)
{
miegoti (50000);
printf("Sveiki, nuo gijos pavadinimo = %s\n", pavadinimas);
}
printf("Gija %s baigta!\n", pavadinimas);
grąžintiNULL;
}
tarptpagrindinis(tuštuma)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, darbuotojas, "X");
pthread_create(&th2, NULL, darbuotojas, "Y");
miegoti (5);
printf("Išėjimas iš pagrindinės programos\n");
grąžinti0;
}
Siūlų tipai
Kai siūlas grįžta iš pagrindinis () funkcija programoje, visos gijos baigiasi ir sistema atlaisvina visus naudojamus programos išteklius. Taip pat, kai išeinate iš bet kurios gijos su tokia komanda kaip an išeiti (), jūsų programa nutrauks visas gijas.
Su pthread_join funkciją, galite palaukti, kol gija nutrūks. Šią funkciją naudojanti gija bus užblokuota, kol nutrūks laukiama gija. Sistemos ištekliai, kuriuos jie naudoja ptread_join.
Kartais būna situacijų, kai prisijungti naudojant pthread_join nėra prasmės; jei, pavyzdžiui, neįmanoma numatyti, kada gija baigsis. Tokiu atveju galite užtikrinti, kad sistema automatiškai grąžintų visus išteklius toje vietoje, kur grįžta gijos.
Norėdami tai padaryti, atitinkamas temas turėtumėte pradėti nuo ATSKIRTA statusą. Pradedant temą, ATSISAKYTI būseną galima nustatyti naudojant gijos atributo reikšmes arba su pthread_detach funkcija:
tarptpthread_attr_setdetachstate(&attr., PTHREAD_CREATE_DETACHED);
tarptpthread_detach(pthread_t siūlas);
Štai pthread_join() naudojimo pavyzdys. Pakeiskite pagrindinę funkciją pirmoje programoje taip:
tarptpagrindinis(tuštuma)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, darbuotojas, "X");
pthread_create(&th2, NULL, darbuotojas, "Y");
miegoti (5);
printf("išėjimas iš pagrindinės programos\n");
pthread_join (th1, NULL);
pthread_join (th2, NULL);
grąžinti0;
}
Kai kompiliuosite ir paleisite programą, jūsų išvestis bus tokia:
Sveiki iš Y gijos
Sveiki iš X gijos
Sveiki iš Y gijos
...
Sveiki iš Y gijos
išeiti iš pagrindinės programos
Sveiki iš X gijos
...
Sveiki iš X gijos
X tema baigta!
Sveiki iš Y gijos
Y siūlas baigtas!
Temos nutraukimas
Galite atšaukti giją iškvietę pthread_cancel, perduodant atitinkamą pthread_t ID:
tarptpthread_cancel(pthread_t siūlas);
Tai galite pamatyti toliau pateiktame kode. Vėlgi, tik pagrindinis funkcija skiriasi:
tarptpagrindinis(tuštuma)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, darbuotojas, "X");
pthread_create(&th2, NULL, darbuotojas, "Y");
miegoti (1);
printf("> Atšaukiama Y gija!!\n");
pthread_cancel (th2);
miegoti (100000);
printf("> Atšaukiama X gija!\n");
pthread_cancel (th1);
printf("išėjimas iš pagrindinės programos\n");
grąžinti0;
}
Kodėl kuriamos gijos?
Operacinės sistemos visada bando paleisti gijas viename ar keliuose procesoriuose, arba iš pačių sukurto sąrašo, arba iš vartotojo sukurto gijų sąrašo. Kai kurios gijos negali paleisti, nes laukia įvesties / išvesties signalo iš aparatinės įrangos. Jie taip pat gali laukti savo noru, laukti atsakymo iš kitos gijos arba juos blokuoti kita gija.
Galite koreguoti išteklius, kuriuos skiriate gijomis, kurias sukuriate naudodami pthread. Tai gali būti tinkinta planavimo politika arba, jei norite, galite pasirinkti planavimo algoritmus, pvz., FIFO arba Round-robin.