Lesere som deg er med på å støtte MUO. Når du foretar et kjøp ved å bruke lenker på nettstedet vårt, kan vi tjene en tilknyttet provisjon. Les mer.

På Linux kan du opprette og administrere tråder i C/C++ ved å bruke POSIX-trådbiblioteket (pthread). I motsetning til andre operativsystemer er det liten forskjell mellom en tråd og en prosess i Linux. Det er derfor Linux ofte refererer til sine tråder som lette prosesser.

Ved å bruke pthread-biblioteket kan du opprette tråder, vente på at de avsluttes, og avslutte dem eksplisitt.

Historien om trådbruk på Linux

Før Linux versjon 2.6 var hovedtrådimplementeringen LinuxThreads. Denne implementeringen hadde betydelige begrensninger når det gjelder ytelse og synkroniseringsoperasjoner. En grense på det maksimale antallet tråder som kunne kjøres begrenset dem til på 1000-tallet.

I 2003 lyktes et team ledet av utviklere fra IBM og RedHat med å lage Innebygd POSIX-trådbibliotek (NPTL) prosjekt tilgjengelig. Den ble først introdusert i RedHat Enterprise versjon 3 for å løse ytelsesproblemer med Java Virtual Machine på Linux. I dag inneholder GNU C-biblioteket implementeringer av begge trådmekanismene.

instagram viewer

Ingen av disse er en implementering av grønne tråder, som en virtuell maskin ville administrere og kjøre i rent brukermodus. Når du bruker pthread-biblioteket, lager kjernen en tråd hver gang et program starter.

Du kan finne trådspesifikk informasjon for alle kjørende prosesser i filene under /proc//task. Dette er standardplasseringen for prosessinformasjon under procfs Linux-standarden. For enkelttrådsapplikasjoner vil det se ut til at det er en oppgavepost med samme verdi som PID under denne katalogen.

Working Logic of Threads

Tråder er som prosesser som kjører på operativsystemet. I enkeltprosessorsystemer (f.eks. mikrokontrollere) simulerer operativsystemkjernen tråder. Dette gjør at transaksjoner kan kjøres samtidig gjennom slicing.

Et enkeltkjerneoperativsystem kan bare kjøre én prosess om gangen. Imidlertid, i multi-core eller multi-prosessor systemer, kan disse prosessene kjøres samtidig.

Trådoppretting i C

Du kan bruke pthread_create funksjon for å opprette en ny tråd. De pthread.h header-filen inkluderer sin signaturdefinisjon sammen med andre trådrelaterte funksjoner. Tråder bruker samme adresseområde og filbeskrivelser som hovedprogrammet.

Pthread-biblioteket inkluderer også nødvendig støtte for mutex og betingede operasjoner som kreves for synkroniseringsoperasjoner.

Når du bruker funksjonene til pthread-biblioteket, må du sørge for at kompilatoren kobler til pthread bibliotek inn i den kjørbare filen. Om nødvendig kan du instruere kompilatoren til å koble til biblioteket ved å bruke -l alternativ:

gcc -o test test_thread.c -lpthread

Funksjonen pthread_create har følgende signatur:

intpthread_create(pthread_t *tråd, konstpthread_attr_t *attr, tomrom *(*start_rutine)(tomrom *), tomrom *arg)

Den returnerer 0 hvis prosedyren er vellykket. Hvis det er et problem, returnerer den en feilkode som ikke er null. I funksjonssignaturen ovenfor:

  • De tråd parameteren er av typen pthread_t. Den opprettede tråden vil alltid være tilgjengelig med denne referansen.
  • De attr parameter lar deg spesifisere tilpasset oppførsel. Du kan bruke en rekke trådspesifikke funksjoner som starter med pthread_attr_ for å sette opp denne verdien. Mulige tilpasninger er planleggingspolicy, stabelstørrelse og frakoblingspolicy.
  • start_rutine spesifiserer funksjonen som tråden skal kjøre.
  • arg representerer en generisk datastruktur sendt til funksjonen av tråden.

Her er et eksempel på en applikasjon:

#inkludere
#inkludere
#inkludere
#inkludere

tomrom *arbeider(tomrom *data)
{
røye *navn = (røye*)data;

til (int jeg = 0; jeg < 120; i++)
{
usleep(50000);
printf("Hei fra trådnavn = %s\n", navn);
}

printf("Tråden %s ferdig!\n", navn);
komme tilbakeNULL;
}

inthoved-(tomrom)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, arbeider, "X");
pthread_create(&th2, NULL, arbeider, "Y");
sove(5);
printf("Avslutter hovedprogrammet\n");
komme tilbake0;
}

Trådtyper

Når en tråd kommer tilbake fra hoved() funksjon i en applikasjon, avsluttes alle tråder og systemet frigjør alle ressurser programmet brukte. På samme måte, når du avslutter en tråd med en kommando som en exit(), vil programmet ditt avslutte alle tråder.

Med pthread_join funksjon, kan du vente til en tråd avsluttes i stedet. Tråden som bruker denne funksjonen vil blokkere til den forventede tråden avsluttes. Ressursene de bruker fra systemet blir ikke returnert selv i tilfeller som avslutning av tråder som kan kobles sammen, uplanlagt av prosessoren, eller til og med unnlatelse av å koble seg sammen med ptread_join.

Noen ganger er det situasjoner der sammenføyning med pthread_join ikke gir mening; hvis det er umulig å forutsi når tråden slutter, for eksempel. I dette tilfellet kan du sørge for at systemet returnerer alle ressurser automatisk på punktet der tråden returnerer.

For å oppnå dette bør du starte de relevante trådene med FRAKOBLET status. Når du starter en tråd, LØSNE status kan settes via en tråd attributt verdier eller med pthread_detach funksjon:

intpthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
intpthread_detach(pthread_t tråd);

Her er et eksempel på bruk av pthread_join(). Bytt ut hovedfunksjonen i det første programmet med følgende:

inthoved-(tomrom)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, arbeider, "X");
pthread_create(&th2, NULL, arbeider, "Y");
sove(5);
printf("avslutter hovedprogrammet\n");
pthread_join (th1, NULL);
pthread_join (th2, NULL);
komme tilbake0;
}

Når du kompilerer og kjører programmet, vil utdataene dine være:

Hei fra tråd Y
Hei fra tråd X
Hei fra tråd Y
...
Hei fra tråd Y
avslutter hovedprogrammet
Hei fra tråd X
...
Hei fra tråd X
Tråd X ferdig!
Hei fra tråd Y
Tråd Y ferdig!

Trådavslutning

Du kan avbryte en tråd med et kall til pthread_cancel, sende den tilsvarende pthread_t id:

intpthread_cancel(pthread_t tråd);

Du kan se dette i aksjon i følgende kode. Igjen, bare hoved- funksjonen er annerledes:

inthoved-(tomrom)
{
pthread_t th1, th2;
pthread_create(&th1, NULL, arbeider, "X");
pthread_create(&th2, NULL, arbeider, "Y");
sove(1);
printf("> Avbryter tråd Y!!\n");
pthread_cancel (th2);
usleep(100000);
printf("> Avbryter tråd X!\n");
pthread_cancel (th1);
printf("avslutter hovedprogrammet\n");
komme tilbake0;
}

Hvorfor lages tråder?

Operativsystemer prøver alltid å kjøre tråder på en eller flere CPUer, enten fra en egenopprettet liste eller fra en brukeropprettet trådliste. Noen tråder kan ikke kjøres fordi de venter på et inngangs-/utgangssignal fra maskinvaren. De kan også vente frivillig, vente på svar fra en annen tråd, eller ha en annen tråd som blokkerer dem.

Du kan justere ressursene du tildeler til tråder du oppretter ved hjelp av pthread. Dette kan være en egendefinert planleggingspolicy, eller du kan velge planleggingsalgoritmer som FIFO eller Round-robin om ønskelig.