Operētājsistēmā Linux varat izveidot un pārvaldīt pavedienus programmā C/C++, izmantojot POSIX pavedienu (pthread) bibliotēku. Atšķirībā no citām operētājsistēmām, Linux ir neliela atšķirība starp pavedienu un procesu. Tāpēc Linux bieži dēvē savus pavedienus kā vieglus procesus.
Izmantojot pthread bibliotēku, varat izveidot pavedienus, gaidīt, līdz tie beidzas, un skaidri tos pārtraukt.
Pavedienu lietošanas vēsture operētājsistēmā Linux
Pirms Linux versijas 2.6 galvenā pavediena ieviešana bija LinuxThreads. Šai ieviešanai bija ievērojami ierobežojumi veiktspējas un sinhronizācijas darbību ziņā. Ierobežojums maksimālajam pavedienu skaitam, ko var palaist, ierobežoja tos līdz 1000 gadiem.
2003. gadā IBM un RedHat izstrādātāju vadītajai komandai izdevās izveidot Vietējā POSIX pavedienu bibliotēka (NPTL) projekts pieejams. Tas pirmo reizi tika ieviests RedHat Enterprise 3. versijā, lai atrisinātu veiktspējas problēmas ar Java virtuālo mašīnu operētājsistēmā Linux. Mūsdienās GNU C bibliotēkā ir abu pavedienu veidošanas mehānismu implementācijas.
Neviens no tiem nav zaļo pavedienu ieviešana, kurus virtuālā mašīna pārvaldītu un darbinātu tikai lietotāja režīmā. Kad izmantojat pthread bibliotēku, kodols izveido pavedienu katru reizi, kad programma tiek startēta.
Failos, kas atrodas zemāk, varat atrast informāciju par pavedienu, kas attiecas uz jebkuru notiekošo procesu /proc/
Vītņu darba loģika
Pavedieni ir līdzīgi procesiem, kas pašlaik darbojas operētājsistēmā. Viena procesora sistēmās (piemēram, mikrokontrolleros) operētājsistēmas kodols simulē pavedienus. Tas ļauj veikt darījumus vienlaikus, izmantojot sadalīšanu.
Viena kodola operētājsistēma vienlaikus var patiešām palaist tikai vienu procesu. Tomēr iekšā daudzkodolu vai vairāku procesoru sistēmas, šie procesi var darboties vienlaikus.
Pavedienu izveide programmā C
Jūs varat izmantot pthread_create funkcija, lai izveidotu jaunu pavedienu. The pthread.h galvenes fails ietver tā paraksta definīciju kopā ar citām ar pavedienu saistītām funkcijām. Pavedieni izmanto to pašu adrešu telpu un failu deskriptorus kā galvenajā programmā.
Pthread bibliotēka ietver arī nepieciešamo atbalstu mutex un nosacījuma operācijām, kas nepieciešamas sinhronizācijas darbībām.
Kad izmantojat pthread bibliotēkas funkcijas, jums ir jānodrošina kompilatora saite uz pthread bibliotēku savā izpildāmā failā. Ja nepieciešams, varat uzdot kompilatoram izveidot saiti uz bibliotēku, izmantojot -l variants:
gcc -o pārbaude test_pavediens.c -lpthread
Funkcijai pthread_create ir šāds paraksts:
starptpthread_create(pthread_t *pavediens, konstpthread_attr_t *attr, nederīgs **(*sākt_rutīna)(nederīgs *), nederīgs *arg)
Tas atgriež 0, ja procedūra ir veiksmīga. Ja rodas problēma, tas atgriež kļūdas kodu, kas nav nulle. Iepriekš minētajā funkcijas parakstā:
- The pavediens parametrs ir tipa pthread_t. Izveidotais pavediens vienmēr būs pieejams ar šo atsauci.
- The attr parametrs ļauj norādīt pielāgotu darbību. Varat izmantot virkni pavedienam raksturīgu funkciju, sākot ar pthread_attr_ lai iestatītu šo vērtību. Iespējamie pielāgojumi ir plānošanas politika, steka lielums un atdalīšanas politika.
- sākuma_rutīna norāda funkciju, ar kuru pavediens darbosies.
- arg apzīmē vispārīgu datu struktūru, ko funkcijai nodod pavediens.
Šeit ir lietojumprogrammas piemērs:
#ietver
#ietver
#ietver
#ietvernederīgs *strādnieks(nederīgs *dati)
{
char *vārds = (char*)dati;
priekš (starpt i = 0; es < 120; i++)
{
aizmigt (50000);
printf("Sveiks no pavediena nosaukuma = %s\n", nosaukums);
}
printf("Pavediens %s pabeigts!\n", nosaukums);
atgrieztiesNULL;
}
starptgalvenais(nederīgs)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, darbinieks, "X");
pthread_create(&th2, NULL, darbinieks, "Y");
Gulēt(5);
printf("Iziet no galvenās programmas\n");
atgriezties0;
}
Vītņu veidi
Kad pavediens atgriežas no galvenais () funkcija lietojumprogrammā, visi pavedieni tiek pārtraukti un sistēma atbrīvo visus programmas izmantotos resursus. Tāpat, izejot no jebkura pavediena ar komandu, piemēram, an Izeja(), jūsu programma pārtrauks visus pavedienus.
Ar pthread_join funkciju, varat gaidīt, līdz pavediens tiks pārtraukts. Pavediens, kas izmanto šo funkciju, tiks bloķēts, līdz paredzētais pavediens beigsies. Resursi, ko viņi izmanto no sistēmas, netiek atgriezti pat tādos gadījumos kā savienojamo pavedienu pārtraukšana, CPU neplānota vai pat neizdodas pievienoties ptread_join.
Dažreiz ir situācijas, kad pievienošanās ar pthread_join nav jēgas; ja, piemēram, nav iespējams paredzēt, kad pavediens beigsies. Šajā gadījumā varat nodrošināt, ka sistēma automātiski atgriež visus resursus vietā, kur pavediens atgriežas.
Lai to panāktu, jāsāk attiecīgie pavedieni ar ATDALĪTS statusu. Uzsākot pavedienu, ATTĪSTĪT statusu var iestatīt, izmantojot pavediena atribūtu vērtības vai ar pthread_detach funkcija:
starptpthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
starptpthread_detach(pthread_t pavediens);
Šeit ir pthread_join() izmantošanas piemērs. Nomainiet galveno funkciju pirmajā programmā ar šādu:
starptgalvenais(nederīgs)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, darbinieks, "X");
pthread_create(&th2, NULL, darbinieks, "Y");
Gulēt(5);
printf("iziet no galvenās programmas\n");
pthread_join (th1, NULL);
pthread_join (th2, NULL);
atgriezties0;
}
Kompilējot un palaižot programmu, jūsu izvade būs:
Sveiki no Y pavediena
Sveiki no pavediena X
Sveiki no Y pavediena
...
Sveiki no Y pavediena
izejot no galvenās programmas
Sveiki no pavediena X
...
Sveiki no pavediena X
Pavediens X pabeigts!
Sveiki no Y pavediena
Pavediens Y pabeigts!
Pavediena pārtraukšana
Jūs varat atcelt pavedienu, izsaucot pthread_cancel, nododot atbilstošo pthread_t id:
starptpthread_cancel(pthread_t pavediens);
To var redzēt darbībā nākamajā kodā. Atkal tikai galvenais funkcija ir atšķirīga:
starptgalvenais(nederīgs)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, darbinieks, "X");
pthread_create(&th2, NULL, darbinieks, "Y");
Gulēt(1);
printf("> Notiek Y pavediena atcelšana!!\n");
pthread_cancel (th2);
aizmigt (100000);
printf("> Tiek atcelts pavediens X!\n");
pthread_cancel (th1);
printf("iziet no galvenās programmas\n");
atgriezties0;
}
Kāpēc tiek veidoti pavedieni?
Operētājsistēmas vienmēr mēģina palaist pavedienus vienā vai vairākos CPU vai nu no paša izveidotā saraksta, vai no lietotāja izveidota pavedienu saraksta. Dažus pavedienus nevar palaist, jo tie gaida ieejas/izejas signālu no aparatūras. Viņi var arī brīvprātīgi gaidīt, gaidot atbildi no cita pavediena vai kāds cits pavediens viņus bloķē.
Varat pielāgot resursus, ko piešķirat pavedieniem, kurus izveidojat, izmantojot pthread. Tā var būt pielāgota plānošanas politika, vai arī varat izvēlēties plānošanas algoritmus, piemēram, FIFO vai Round-robin, ja vēlaties.