Čitatelia ako vy pomáhajú podporovať MUO. Keď uskutočníte nákup pomocou odkazov na našej stránke, môžeme získať pridruženú províziu. Čítaj viac.

V systéme Linux môžete vytvárať a spravovať vlákna v C/C++ pomocou knižnice vlákien POSIX (pthread). Na rozdiel od iných operačných systémov je v Linuxe malý rozdiel medzi vláknom a procesom. To je dôvod, prečo Linux často označuje svoje vlákna ako ľahké procesy.

Pomocou knižnice pthread môžete vytvárať vlákna, čakať na ich ukončenie a explicitne ich ukončiť.

História používania vlákien v systéme Linux

Pred verziou Linuxu 2.6 bola implementácia hlavného vlákna LinuxThreads. Táto implementácia mala značné limity z hľadiska výkonu a synchronizačných operácií. Obmedzenie maximálneho počtu vlákien, ktoré bolo možné spustiť, ich obmedzilo na 1000.

V roku 2003 sa tímu pod vedením vývojárov z IBM a RedHat podarilo vytvoriť Natívna knižnica vlákien POSIX (NPTL) projekt k dispozícii. Prvýkrát bol predstavený vo verzii RedHat Enterprise 3 na riešenie problémov s výkonom Java Virtual Machine v systéme Linux. Knižnica GNU C dnes obsahuje implementácie oboch mechanizmov vlákna.

instagram viewer

Ani jedno z toho nie je implementáciou zelených vlákien, ktoré by virtuálny stroj spravoval a spúšťal v čisto užívateľskom režime. Keď použijete knižnicu pthread, jadro vytvorí vlákno pri každom spustení programu.

Informácie špecifické pre vlákna pre každý spustený proces nájdete v súboroch pod /proc//task. Toto je štandardné miesto pre informácie o procese pod štandard procfs Linux. Pri jednovláknových aplikáciách sa zdá, že v tomto adresári je záznam úlohy s rovnakou hodnotou ako PID.

Pracovná logika vlákien

Vlákna sú ako procesy, ktoré momentálne bežia v operačnom systéme. V jednoprocesorových systémoch (napr. mikrokontroléry) jadro operačného systému simuluje vlákna. To umožňuje, aby transakcie prebiehali súčasne prostredníctvom krájania.

Jednojadrový operačný systém môže skutočne spustiť iba jeden proces súčasne. Avšak v viacjadrové alebo viacprocesorové systémy, tieto procesy môžu prebiehať súčasne.

Vytvorenie vlákna v C

Môžete použiť pthread_create funkcia na vytvorenie nového vlákna. The pthread.h hlavičkový súbor obsahuje definíciu podpisu spolu s ďalšími funkciami súvisiacimi s vláknami. Vlákna používajú rovnaký adresný priestor a deskriptory súborov ako hlavný program.

Knižnica pthread obsahuje aj potrebnú podporu pre mutex a podmienené operácie potrebné pre synchronizačné operácie.

Keď používate funkcie knižnice pthread, musíte zabezpečiť, aby kompilátor prepojil s pthread knižnice do spustiteľného súboru. Ak je to potrebné, môžete dať kompilátoru pokyn, aby sa prepojil s knižnicou pomocou -l možnosť:

gcc -o test test_thread.c -lpthread

Funkcia pthread_create má nasledujúci podpis:

intpthread_create(pthread_t *vlákno, konštpthread_attr_t *attr, neplatné *(*start_routine)(neplatné *), neplatné *arg)

Ak je postup úspešný, vráti 0. Ak sa vyskytne problém, vráti nenulový kód chyby. Vo vyššie uvedenom podpise funkcie:

  • The niť parameter je typu pthread_t. Vytvorené vlákno bude vždy prístupné s týmto odkazom.
  • The attr parameter vám umožňuje špecifikovať vlastné správanie. Môžete použiť sériu funkcií špecifických pre vlákna počnúc pthread_attr_ na nastavenie tejto hodnoty. Možné prispôsobenia sú politika plánovania, veľkosť zásobníka a politika odpojenia.
  • štart_rutina určuje funkciu, ktorú vlákno spustí.
  • arg predstavuje všeobecnú dátovú štruktúru odovzdanú funkcii vláknom.

Tu je príklad aplikácie:

#zahŕňajú
#zahŕňajú
#zahŕňajú
#zahŕňajú

neplatné *pracovník(neplatné *údaje)
{
char *meno = (char*) údaje;

pre (int i = 0; ja < 120; i++)
{
spať (50000);
printf("Ahoj z názvu vlákna = %s\n", meno);
}

printf("Vlákno %s hotové!\n", názov);
vrátiťNULOVÝ;
}

intHlavná(neplatné)
{
pthread_t th1, th2;
pthread_create(&th1, NULOVÝ, pracovník, "X");
pthread_create(&th2, NULOVÝ, pracovník, "Y");
spať (5);
printf("Ukončenie hlavného programu\n");
vrátiť0;
}

Typy vlákien

Keď sa vlákno vráti z Hlavná() všetky vlákna sa ukončia a systém uvoľní všetky zdroje, ktoré program použil. Podobne pri opúšťaní ľubovoľného vlákna pomocou príkazu ako an VÝCHOD(), váš program ukončí všetky vlákna.

S pthread_join namiesto toho môžete počkať na ukončenie vlákna. Vlákno používajúce túto funkciu sa zablokuje, kým sa neskončí očakávané vlákno. Zdroje, ktoré používajú zo systému, sa nevracajú ani v prípadoch, ako je ukončenie spájateľných vlákien, neplánované CPU alebo dokonca zlyhanie spojenia s ptread_join.

Niekedy nastanú situácie, keď spojenie s pthread_join nedáva zmysel; ak nie je možné predpovedať, kedy sa vlákno skončí, napr. V tomto prípade môžete zabezpečiť, že systém vráti všetky prostriedky automaticky v bode, kde sa vlákno vráti.

Aby ste to dosiahli, mali by ste začať príslušné vlákna s DETACHED postavenie. Keď začínate vlákno, ODPOJIŤ stav možno nastaviť pomocou hodnôt atribútu vlákna alebo pomocou pthread_detach funkcia:

intpthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
intpthread_detach(pthread_t vlákno);

Tu je príklad použitia pthread_join(). Nahraďte hlavnú funkciu v prvom programe nasledujúcim:

intHlavná(neplatné)
{
pthread_t th1, th2;
pthread_create(&th1, NULOVÝ, pracovník, "X");
pthread_create(&th2, NULOVÝ, pracovník, "Y");
spať (5);
printf("opustenie hlavného programu\n");
pthread_join (th1, NULOVÝ);
pthread_join (th2, NULOVÝ);
vrátiť0;
}

Keď skompilujete a spustíte program, váš výstup bude:

Ahoj z vlákna Y
Ahoj z vlákna X
Ahoj z vlákna Y
...
Ahoj z vlákna Y
opustenie hlavného programu
Ahoj z vlákna X
...
Ahoj z vlákna X
Vlákno X hotové!
Ahoj z vlákna Y
Vlákno Y hotovo!

Ukončenie vlákna

Vlákno môžete zrušiť volaním pthread_cancel a odovzdaním zodpovedajúceho vlákna pthread_t id:

intpthread_cancel(pthread_t vlákno);

Môžete to vidieť v akcii v nasledujúcom kóde. Opäť len ten Hlavná funkcia je iná:

intHlavná(neplatné)
{
pthread_t th1, th2;
pthread_create(&th1, NULOVÝ, pracovník, "X");
pthread_create(&th2, NULOVÝ, pracovník, "Y");
spať (1);
printf("> Ruším vlákno Y!!\n");
pthread_cancel (th2);
spať (100000);
printf("> Ruším vlákno X!\n");
pthread_cancel (th1);
printf("opustenie hlavného programu\n");
vrátiť0;
}

Prečo sa vytvárajú vlákna?

Operačné systémy sa vždy pokúšajú spustiť vlákna na jednom alebo viacerých procesoroch, a to buď z vlastného zoznamu alebo zo zoznamu vlákien vytvoreného používateľom. Niektoré vlákna nemôžu bežať, pretože čakajú na vstupný/výstupný signál z hardvéru. Môžu tiež čakať dobrovoľne, čakať na odpoveď z iného vlákna alebo ich blokuje iné vlákno.

Prostriedky, ktoré prideľujete vláknam, ktoré vytvoríte, môžete upraviť pomocou pthread. Môže to byť vlastná plánovacia politika, alebo si v prípade potreby môžete vybrať plánovacie algoritmy ako FIFO alebo Round-robin.