Kaltaisesi lukijat auttavat tukemaan MUO: ta. Kun teet ostoksen käyttämällä sivustollamme olevia linkkejä, voimme ansaita kumppanipalkkion. Lue lisää.

Linuxissa voit luoda ja hallita säikeitä C/C++:ssa käyttämällä POSIX-säiekirjastoa (pthread). Toisin kuin muissa käyttöjärjestelmissä, säikeen ja prosessin välillä on vain vähän eroa Linuxissa. Siksi Linux usein viittaa säikeisiinsä kevyiksi prosesseiksi.

Käyttämällä pthread-kirjastoa voit luoda säikeitä, odottaa niiden päättymistä ja lopettaa ne nimenomaisesti.

Säikeen käytön historia Linuxissa

Ennen Linux-versiota 2.6 pääsäikeen toteutus oli LinuxThreads. Tällä toteutuksella oli merkittäviä rajoituksia suorituskyvyn ja synkronointitoimintojen suhteen. Ajettavien säikeiden enimmäismäärän rajoitus rajoitti ne 1000 luvulle.

Vuonna 2003 IBM: n ja RedHatin kehittäjien johtama tiimi onnistui tekemään sen Alkuperäinen POSIX-säiekirjasto (NPTL) -projekti saatavilla. Se esiteltiin ensimmäisen kerran RedHat Enterprise -versiossa 3 ratkaisemaan suorituskykyongelmia Java Virtual Machinen kanssa Linuxissa. Nykyään GNU C -kirjasto sisältää toteutuksia molemmista säikeistysmekanismeista.

instagram viewer

Kumpikaan näistä ei ole vihreiden säikeiden toteutus, jota virtuaalikone hallitsisi ja ajaisi puhtaasti käyttäjätilassa. Kun käytät pthread-kirjastoa, ydin luo säikeen aina, kun ohjelma käynnistyy.

Löydät säiekohtaiset tiedot kaikista käynnissä olevista prosesseista alla olevista tiedostoista /proc//task. Tämä on alla olevien prosessitietojen vakiosijainti procfs Linux -standardi. Yksisäikeisissä sovelluksissa näyttää siltä, ​​että tässä hakemistossa on tehtävätietue, jolla on sama arvo kuin PID.

Säikeiden toimiva logiikka

Säikeet ovat kuin käyttöjärjestelmässä tällä hetkellä käynnissä olevia prosesseja. Yhden prosessorin järjestelmissä (esim. mikro-ohjaimet) käyttöjärjestelmän ydin simuloi säikeitä. Tämä mahdollistaa tapahtumien suorittamisen samanaikaisesti viipaloinnin kautta.

Yksiytiminen käyttöjärjestelmä voi todella ajaa vain yhtä prosessia kerrallaan. Kuitenkin sisään moniytimiset tai moniprosessorijärjestelmät, nämä prosessit voivat toimia samanaikaisesti.

Viestiketjun luominen C: ssä

Voit käyttää pthread_create toiminto luodaksesi uuden säikeen. The pthread.h otsikkotiedosto sisältää sen allekirjoitusmäärittelyn muiden säikeeseen liittyvien toimintojen ohella. Säikeet käyttävät samaa osoiteavaruutta ja tiedostokuvauksia kuin pääohjelma.

Pthread-kirjasto sisältää myös tarvittavan tuen synkronointitoimintoihin tarvittaville mutex- ja ehdollisille operaatioille.

Kun käytät pthread-kirjaston toimintoja, sinun on varmistettava, että kääntäjä linkittää pthread kirjasto suoritettavaan tiedostoon. Tarvittaessa voit ohjeistaa kääntäjää linkittämään kirjastoon käyttämällä -l vaihtoehto:

gcc -o testata test_thread.c -lpthread

Pthread_create-funktiolla on seuraava allekirjoitus:

intpthread_create(pthread_t *lanka, konstpthread_attr_t *attr, mitätön **(*aloitus_rutiini)(mitätön *), mitätön *arg)

Se palauttaa 0, jos toimenpide onnistuu. Jos on ongelma, se palauttaa nollasta poikkeavan virhekoodin. Yllä olevassa funktion allekirjoituksessa:

  • The lanka parametri on tyyppiä pthread_t. Luotu säie on aina käytettävissä tällä viitteellä.
  • The attr parametrin avulla voit määrittää mukautetun toiminnan. Voit käyttää useita lankakohtaisia ​​toimintoja alkaen pthread_attr_ asettaaksesi tämän arvon. Mahdollisia mukautuksia ovat ajoituskäytäntö, pinon koko ja irrotuskäytäntö.
  • aloitus_rutiini määrittää toiminnon, jota säiettä ajaa.
  • arg edustaa yleistä tietorakennetta, jonka säie välittää funktiolle.

Tässä esimerkki sovelluksesta:

#sisältää
#sisältää
#sisältää
#sisältää

mitätön *työntekijä(mitätön *tiedot)
{
hiiltyä *nimi = (hiiltyä*)tiedot;

varten (int minä = 0; minä < 120; i++)
{
sinä nukut(50000);
printf("Hei ketjun nimestä = %s\n", nimi);
}

printf("Säie %s valmis!\n", nimi);
palataTYHJÄ;
}

intpää(mitätön)
{
pthread_t th1, th2;
pthread_create(&th1, TYHJÄ, työntekijä, "X");
pthread_create(&th2, TYHJÄ, työntekijä, "Y");
nukkua(5);
printf("Poistutaan pääohjelmasta\n");
palata0;
}

Lankatyypit

Kun lanka palaa pää() -toiminto sovelluksessa, kaikki säikeet päättyvät ja järjestelmä vapauttaa kaikki ohjelman käyttämät resurssit. Samoin poistuttaessa mistä tahansa säikeestä komennolla, kuten an exit(), ohjelmasi lopettaa kaikki säikeet.

Kanssa pthread_join -funktion sijaan voit odottaa säikeen päättymistä. Tätä toimintoa käyttävä säie estetään, kunnes odotettu säie päättyy. Resursseja, joita he käyttävät järjestelmästä, ei palauteta edes silloin, kun liitettävissä olevat säikeet päättyvät, CPU ei ole ajoittanut tai jopa epäonnistuu ptread_join.

Joskus on tilanteita, joissa pthread_joinilla liittyminen ei ole järkevää; jos on mahdotonta ennustaa, milloin lanka esimerkiksi päättyy. Tässä tapauksessa voit varmistaa, että järjestelmä palauttaa kaikki resurssit automaattisesti kohtaan, jossa säie palaa.

Tämän saavuttamiseksi sinun tulee aloittaa asiaankuuluvat säikeet ERILLINEN Tila. Kun aloitat ketjun, IRROTA tila voidaan asettaa säikeen attribuuttiarvojen avulla tai pthread_detach toiminto:

intpthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
intpthread_detach(pthread_t lanka);

Tässä on esimerkki pthread_join() käytöstä. Korvaa ensimmäisen ohjelman päätoiminto seuraavasti:

intpää(mitätön)
{
pthread_t th1, th2;
pthread_create(&th1, TYHJÄ, työntekijä, "X");
pthread_create(&th2, TYHJÄ, työntekijä, "Y");
nukkua(5);
printf("poistuminen pääohjelmasta\n");
pthread_join (th1, TYHJÄ);
pthread_join (th2, TYHJÄ);
palata0;
}

Kun käännät ja suoritat ohjelman, tulos on:

Terve ketjusta Y
Terve ketjusta X
Terve ketjusta Y
...
Terve ketjusta Y
pääohjelmasta poistuminen
Terve ketjusta X
...
Terve ketjusta X
Lanka X valmis!
Terve ketjusta Y
Lanka Y valmis!

Viestiketjun lopetus

Voit peruuttaa säikeen kutsumalla pthread_cancel, ohittaen vastaavan pthread_t id:

intpthread_cancel(pthread_t lanka);

Voit nähdä tämän toiminnassa seuraavasta koodista. Jälleen vain pää toiminto on erilainen:

intpää(mitätön)
{
pthread_t th1, th2;
pthread_create(&th1, TYHJÄ, työntekijä, "X");
pthread_create(&th2, TYHJÄ, työntekijä, "Y");
nukkua(1);
printf("> Peruutetaan säiettä Y!!\n");
pthread_cancel (th2);
sinä nukut(100000);
printf("> Peruutetaan säiettä X!\n");
pthread_cancel (th1);
printf("poistuminen pääohjelmasta\n");
palata0;
}

Miksi ketjuja luodaan?

Käyttöjärjestelmät yrittävät aina ajaa säikeitä yhdessä tai useammassa suorittimessa joko itse luomasta luettelosta tai käyttäjän luomasta säieluettelosta. Jotkut säikeet eivät voi toimia, koska ne odottavat tulo-/lähtösignaalia laitteistolta. He voivat myös odottaa vapaaehtoisesti, odottaa vastausta toiselta säikeeltä tai joku toinen säie estää heidät.

Voit säätää resursseja, jotka varaat säikeille, jotka luot pthreadilla. Tämä voi olla mukautettu ajoituskäytäntö tai voit halutessasi valita aikataulutusalgoritmeja, kuten FIFO tai Round-robin.