Pthread_join -funksjon på C -språk med enkelt- og flere trådeksempler

Pthread_join -funksjon på C -språk med enkelt- og flere trådeksempler
C -språket tilbyr muligheten til å utvikle multitasking -programmene ved å bruke Pthread -biblioteket i POSIX -standarden. Denne metoden øker hastigheten på det ferdige programmet ved å utføre flere tråder parallelt med hovedfunksjonen.

For å lage et vellykket program ved hjelp av denne programmeringsmetoden, må du ta noen spesielle hensyn. For eksempel, hvis utførelsestidene til en tråd er lengre enn de i hoved () -funksjonen og den blir fullt utført, vil programmet avslutte, og det vil alle tilknyttede trådene, enten de har fullført oppgaven sin eller ikke.

Dette kan forårsake kritiske problemer fordi en tråd som avsluttes uventet, kan være i ferd med å lagre en brukergenerert data, skrive til en fil eller en enhet eller utføre en annen viktig oppgave.

I denne Linux -hint -artikkelen vil du lære hvordan du bruker Pthread_Join () -funksjonen for å sikre at en eller flere tråder blir pålitelig avsluttet før et program går ut eller gjenopptas.

Syntaks av Pthread_Join () -funksjonen på C -språk

int pthread_join (pthread_t tråd, void ** retval);

Beskrivelse av Pthread_Join () -funksjonen på C -språk

Pthread_join () -funksjonen venter på prosessen den kalles til en tråd er ferdig med oppgaven. Denne funksjonen suspenderer funksjonen som den kalles til underprosessen som er spesifisert av identifiseringen i trådinngangsargumentet, slutter.

Når tråden er ferdig med oppgaven, gjenopptar programmet utførelsen fra neste linje i koden som kaller pthread_join ().

Når underprosessen slutter, returnerer PTHREAD_JOIN () -funksjonen utgangsstatusen til tråden i retval-argumentet.

Deretter ser vi inngangsargumentene til pthread_join () sammen med en beskrivelse av funksjonen som tilfredsstiller hvert av disse argumentene:

tråd: Dette inngangsargumentet er en dataverdi av pthread_t -typen og er identifikatoren for underprosessen som PTHREAD_JOIN () -funksjonen bør forvente.

Verdien av identifikatoren genereres av systemet og oppnås som et resultat av Pthread_Create () -funksjonen i dens utgangsargument tråd når tråden opprettes.

Retval: Dette inngangsargumentet er en peker til (ugyldig *) der Pthread_join () -funksjonen lagrer utgangsstatus for tråden.

Hvis pthread_join () kommer tilbake, returnerer den 0 som resultat. Hvis det oppstår en feil, returnerer denne funksjonen et heltall med en verdi som representerer feilen som oppsto. Senere vil du se en spesiell seksjon som beskriver alle feilene som denne funksjonen kan generere og hvordan du kan identifisere dem.

Pthread_join () -funksjonen er definert i pthread.H header. For å bruke den, må følgende overskrifter inkluderes i ".C ”-fil, som vist i følgende:

#inkludere
#inkludere

Merk: Det er viktig at du bare bruker denne funksjonen når det er nødvendig, da du kan utvide utførelsestiden for et program ved å stoppe den ene prosessen for å vente på at den andre skal fullføre.

Samlingsfeil i programmer med tråder

Når du sammenstiller GCC -programmene som bruker tråder, kan samlingen mislykkes hvis det ikke gjøres riktig fra kommandolinjen.

Den vanligste feilmeldingen som er utstedt av kompilatoren sier at en av trådfunksjonene som vi refererer til i koden ikke er definert.

Disse feilene resulterer ofte i å kaste bort en verdifull tid i å sjekke overskriftene som vi satte inn i koden, deres integritet og katalogene som er tilknyttet kompilatoren, siden alt indikerer at problemet er der.

Selv om funksjonene som forårsaker feilen er definert i “Pthread.H ”-overskrift og er inkludert i koden, kompilatoren gjenkjenner ikke disse funksjonene med mindre Pthread -biblioteket kalles fra kommandolinjen under samlingen.

I den følgende illustrasjonen kan du se riktig måte å ringe PThread -biblioteket (uthevet i grønt) fra kommandokonsollen under sammenstilling av programmer med tråder:

~ $ gcc -pthread bane/filnavn.c -o out_name

Som vi kan se i følgende figur, forsvinner feilen når Pthread -biblioteket kalles under samlingen.

Hvordan du bruker pthread_join () -funksjonen for å vente på en tråd for å fullføre utførelsen på C -språket

I dette eksemplet lager vi en tråd som har en lengre utførelsestid enn hovedfunksjonen (). Etter at vi har opprettet tråden, bruker vi pthread_join () for å vente på hele utførelsen av tråden før vi forlater main () -funksjonen og avslutter programmet.

For dette formålet oppretter vi tråden () -funksjonen som utfører tråden. Denne funksjonen er en "for" -sløyfe med 5 sykluser i en sekunds varighet, som hver skriver ut "Sekunder til slutten av tråden:”Melding, etterfulgt av antall gjenværende sekunder i kommandokonsollen.

Fra main () -funksjonen lager vi tråden_1 med Pthread_Create () -funksjonen. Deretter kaller vi Pthread_Join () -funksjonen for å vente på at underprosessen skal fullføre utførelsen før du forlater programmet.

PTHREAD_JOIN () Funksjonsanropet følger med tråden_1 -identifikatoren som det første inngangsargumentet og retvalet som null i det andre argumentet. Vi ser følgende komplette kode for dette eksemplet:

#inkludere
#inkludere
#inkludere
#inkludere
void* thread_f (void* n);
int main ()

pthread_t thread_1;
pthread_create (& thread_1, null, thread_f, null);
pthread_join (tråd_1, null);
retur 0;

void* thread_f (void* n)

for (int a = 5; a!= 0; en--)

printf ("sekunder til slutten av tråden: %i \ n", a);
søvn (1);

printf ("enden av tråden \ n");
pthread_exit (n);

Følgende bilde viser sammenstilling og utførelse av denne koden:

Som vi så på figuren, fullførte "for" -sløyfen sine 5 sykluser og programmet er stengt etter at Thread_1 avsluttet utførelsen. La oss se hva som skjer hvis vi fjerner Pthread_Join () -funksjonen. Sett sammen og kjør følgende kode:

Som vi kan se på figuren, kunne ikke "for" sløyfen til tråd_1 fullføre ett pass før hovedfunksjonen () er fullt utført og programmet avsluttes.

Hvordan bruke Pthread_Join () -funksjonen for å vente på at en flere tråd skal fullføre utførelsen på C -språket

I dette eksemplet vil vi vise deg hvordan du bruker Pthread_Join () -funksjonen for å vente på at flere samtidige tråder skal fullføre.

For å gjøre dette bruker vi koden fra forrige eksempel og legger til en andre tråd som er tråd_2 og en andre rutine som er tråd_f_2 () som utfører parallelt med tråd_1. Utførelsestiden for denne rutinen er dobbelt så lang som for tråd_f_1 () som tar 10 sekunder.

Metoden som vi bruker er å lage de to trådene etter hverandre ved hjelp av Pthread_Create () -funksjonen. Deretter kaller vi først Pthread_Join () -funksjonen med den kortest løpende tråden, etterfulgt av en ny samtale til denne funksjonen med den lengst løpende tråden. Følgende er den komplette koden for dette eksemplet:

#inkludere
#inkludere
#inkludere
#inkludere
void* thread_f_1 (void* n);
void* thread_f_2 (void* n);
int main ()

pthread_t thread_1;
pthread_t thread_2;
pthread_create (& thread_1, null, thread_f_1, null);
pthread_create (& thread_2, null, thread_f_2, null);
pthread_join (tråd_1, null);
pthread_join (tråd_2, null);
retur 0;

void* thread_f_1 (void* n)

for (int a = 5; a!= 0; en--)

printf ("sekunder til slutten av tråden 1: %i \ n", a);
søvn (1);

printf ("enden av tråden 1 \ n");
pthread_exit (n);

void* thread_f_2 (void* n)

for (int a = 10; a!= 0; en--)

printf ("sekunder til slutten av tråden 2: %i \ n", a);
søvn (1);

printf ("enden av tråden 2 \ n");
pthread_exit (n);

Som vi ser i følgende bilde, fullførte begge trådene utførelsen:

Feil som PTHREAD_JOIN () -funksjonen kan returnere: Hva er de og hvordan kan de oppdages?

Når en feil oppstår, returnerer Pthread_Join () -funksjonen en av følgende forhåndsdefinerte koder:

Esrch: Den spesifiserte identifikatoren er ikke assosiert med noen tråd.

Einval: Tråden er ikke sammenføyelig, eller en annen tråd venter allerede på å bli med i denne.

Edeadlk: Det oppdages et krasj.

Disse feilene er forhåndsdefinert i “Errno.H ”-overskrift og returneres som et resultat i utgangs heltallet til Pthread_Join () -funksjonen, ikke i den globale variabelen errno.

Følgende er koden fra forrige eksempel der vi legger til en "if" -tilstand for å avgjøre om det oppstod en feil. I så fall legger programmet inn i en brytertilstand som identifiserer feilen og viser en melding i kommandokonsollen med den spesifikke beskrivelsen av den feilen.

Vi inkluderer også “Errno.H ”header og erklærer feilvariabelen som vil være“ hvis ”og“ bryter ”-forholdene.

For å generere feilen, refererer vi til tråden_2 i trådinngangsargumentet til Pthread_Join () -funksjonen som ikke er opprettet.

#inkludere
#inkludere
#inkludere
#inkludere
#inkludere
void* thread_f (void* n);
int main ()
int feil;
pthread_t thread_1;
pthread_t thread_2;
pthread_create (& thread_1, null, thread_f, null);
feil = pthread_join (tråd_2, null);
hvis (feil!= 0)
bryter (feil)
sak esrch:
printf ("Identifikatoren er ikke assosiert med noen tråd \ n");
gå i stykker;
Case Einval:
printf ("tråd som ikke er sammenføyelig eller en annen tråd venter allerede \ n");
gå i stykker;
sak Edeadlk:
printf ("Det ble oppdaget et krasj.\ n ");
gå i stykker;

retur 0;

void* thread_f (void* n)

for (int a = 5; a!= 0; en--)

printf ("sekunder til slutten av tråden: %i \ n", a);
søvn (1);

printf ("enden av tråden \ n");
pthread_exit (n);

Følgende bilde viser sammenstilling og utførelse av denne koden. Se hvordan programmet går inn i "hvis" -uttalelsen og ESRCH-forekomsten av bryteruttalelsen som indikerer at tråden_2-identifikatoren peker på en ikke-eksisterende tråd. Du kan også se at utførelsen av tråd_1 er ufullstendig.

Konklusjon

I denne Linux-hint-artikkelen viste vi deg hvordan du implementerer Pthread_Join () -funksjonen fra trådbiblioteket for å sikre en fullstendig utførelse av en underprosess.

Vi forklarte syntaks for denne funksjonen og beskrev hvert av inngangsargumentene og hvordan vi kan skaffe dataene som må sendes i dem. Vi implementerte deretter funksjonen i et praktisk eksempel med kodebiter og bilder for å vise hvordan du kan bruke Pthread_Join () -funksjonen for å sikre en fullstendig og pålitelig utførelse av en tråd.

Vi viste deg også hvordan du kan koble trådbiblioteket riktig for feilfri sammenstilling. I en spesiell seksjon viste vi deg hvordan du kan oppdage og identifisere feilene som Pthread_Join () -funksjonen kan generere.