Pthread_create -funksjon på C -språk

Pthread_create -funksjon på C -språk

Konseptuelt er et program en enkelt tråd som utfører flere serielle oppgaver, etter hverandre.
C -språket lar oss skrive multithreaded -programmer ved å bruke PThread -biblioteket til POSIX -standarden.
Et flertrådd program er en tråd eller oppgave som går parallelt og samtidig med hovedprogrammet og andre tråder åpnet av det samme programmet i en del av det.

I dette Linux hint Artikkel, du lærer hvordan du lager en tråd fra et hovedprogram ved hjelp av pthread_create () Funksjonen til Pthread -biblioteket.

Dette forklarer teoretiske virkninger av denne funksjonen, syntaks, inngangs- og utgangsargumenter og datatypen som er akseptert i hvert tilfelle.
Vi vil deretter bruke det vi har lært i praktiske eksempler, inkludert kodebiter og bilder, der vi lager og synkroniserer tråder fra hovedfunksjonen.

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

int pthread_create (pthread_t *begrenset tråden,
const pthread_attr_t *Begrens ATTR,
void *( *start_routine) (void *),
ugyldig *Begrens Arg);

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

De pthread_create () Funksjon skaper en tråd og utfører den, parallelt og samtidig med programmet som opprettet den. Denne funksjonen utfører rutinen som er spesifisert av pekeren i inngangen start_routine Ved å gi det inndataargumentet Arg.

La oss deretter se på inngangs- og utgangsargumentene til pthread_create () i detalj, samt en beskrivelse av verket, utfører hvert av disse argumentene innen funksjonen.

tråd: Dette er et utgangsargument som returnerer identifikatoren til den opprettede tråden. Denne identifikatoren brukes til å referere den til i visse trådstyringsfunksjoner som Pthread_Join () eller Pthread_Cancel ().

attr: Denne oppføringen er pekeren til en struktur av typen pthread_att_t hvis medlemmer spesifiserer attributtene til den nye tråden. Når dette argumentet blir sendt til NULL, blir attributtene til den nye tråden tatt med standardparametere.

start_routine: Dette er pekeren til funksjonen som vil bli utført av den nye tråden.

Arg: Dette er pekeren til argumentet om at hovedfunksjonen går til den nye tråden.

Hvis tråden opprettes vellykket, pthread_create () Returnerer 0 som resultat. Hvis det oppstår en feil, returnerer den -1 og lagrer i den globale variabelen errno den spesifikke numeriske verdien som representerer den feilen.

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

#inkludere
#inkludere

Samlingsfeil i programmer med tråder

Når du sammenstiller GCC -programmer som bruker tråder, kan samlingen mislykkes hvis ikke gjøres riktig fra kommandolinjen.
Den vanligste feilmeldingen utstedt av kompilatoren sier at en av trådfunksjonene vi refererer til i koden ikke er definert.

Disse feilene resulterer ofte i å kaste bort verdifull tid på å sjekke overskriftene vi har satt inn i koden, deres integritet og katalogene knyttet til kompilatoren, siden alt indikerer at problemet er der.
Selv om funksjonene som forårsaker feilen er definert i “Pthread.H ”header og inkludert i koden, gjenkjenner ikke kompilatoren disse funksjonene med mindre Pthread -biblioteket blir kalt fra kommandolinjen under samlingen.

Nedenfor kan du se på grønt den riktige måten å ringe PThread -biblioteket fra kommandokonsollen under sammenstilling av programmer med tråder:

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

Som vist på figuren nedenfor, forsvinner feilen når Pthread -biblioteket kalles under samlingen.

Hvordan lage og utføre en tråd med Pthread_Create () -funksjonen på C -språket

I dette eksemplet vil vi forklare hvordan pthread_create () virker. For å gjøre dette, vil vi lage en hovedfunksjon og derfra åpne en tråd som utfører tråd_funksjon () funksjon parallelt med hovedfunksjon.

Koden for dette eksemplet består av to seksjoner, hoved() funksjon og tråd_funksjon () funksjon, som er tråden.
Deretter vil vi forklare hver av de to funksjonene hver for seg og deretter sette dem sammen for å kompilere og kjøre koden.

tråd_funksjon (): Denne funksjonen består av en til Loop med 5 sykluser, hvorav meldingen “Fra tråden” vises i kommandokonsollen og etter en forsinkelse på 3 sekunder gjentas syklusen igjen. Meldingen om denne funksjonen er sammenflettet med den til hoved() funksjon slik at du i sanntid kan se hva hver av prosessene gjør samtidig.

Neste, vi ikke ser nclusi tråd_funksjon () funksjon og definisjonen av prototypen:

void* thread_function (void* n);
void* thread_function (void* n)

for (int a = 0; a!= 5; A ++)

printf (“Fra tråden \ n”);
søvn (3);

printf (“nclus thread \ n”);
pthread_exit (n);

hovedfunksjon: I dette eksemplet hoved() Funksjonen er nclusióne for å definere variablene og lage tråden.

Det første trinnet i å lage en tråd er å definere en variabel av typen pthread_t at NCL fungerer som identifikatoren til tråden. I dette eksemplet kaller vi ikke denne variabelen Tråd_1.

For å nclus tråden, kaller vi pthread_create () funksjon og passere tråden identifikator tråd_1 som det første argumentet.
Attributtene til tråden som skal opprettes er forhåndsinnstilt i dette tilfellet, så det andre inngangsargumentet er null.
Som det tredje argumentet overfører vi pekeren til funksjonen som skal utføres i den nye tråden, i dette tilfellet tråd_funksjon ().
Siden vi ikke trenger å overføre noen argumenter til den nye tråden i dette eksemplet, er Arg -pekeren NCL også null.

Etter å ha ringt pthread_create (), Den nye tråden begynner utførelse og funksjonen hoved() kommer inn i en til Loop på 5 sykluser, som hver skriver ut meldingen “Fra hovedfunksjon” hekket med meldingen “Fra tråden” av funksjonen tråd_funksjon (). Etter hver melding settes en forsinkelse på 3 sekunder inn i for -løkkene til begge funksjonene før en ny syklus startes.

Nedenfor kan du se NClusi funksjonen hoved(), nclusión av de nødvendige overskriftene, og erklæringen om prototypen av funksjonen thread_function ():

#inkludere
#inkludere
#inkludere
#inkludere
void* thread_function (void* data);
int main ()

pthread_t thread_1;
printf ("Opprette tråden ... \ n");
pthread_create (& thread_1, null, thread_function, null);
for (int a = 0; a!= 5; a ++)

printf ("fra hovedfunksjon \ n");
søvn (3);

søvn (3);
retur 0;

Deretter ser vi hele koden for dette eksemplet. Kopier og lim inn dette fragmentet i en fil med en ".C ”-forlengelse. Kompilere koden og kjøre den for å se hvordan hoved() funksjon og den nye tråden utfører oppgavene sine samtidig.

#inkludere
#inkludere
#inkludere
#inkludere
void* thread_function (void* data);
int main ()

pthread_t thread_1;
printf ("Opprette tråden ... \ n");
pthread_create (& thread_1, null, thread_function, null);
for (int a = 0; a!= 5; a ++)

printf ("fra hovedfunksjon \ n");
søvn (3);

retur 0;

/******************************************************** ****************/
void* thread_function (void* n)

for (int a = 0; a!= 5; A ++)

printf ("fra tråden \ n");
søvn (3);

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

Bildet vi ser nedenfor viser oppgaven utført av tråden vi opprettet med pthread_create () funksjon parallelt med oppgaven til hoved() funksjon, og meldingene hver av dem sender til kommandokonsollen:

Synkronisering av tråder på C -språket

I koden til forrige eksempel er utførelsestiden for tråden kortere enn den for hoved() funksjon og derfor gjør begge jobben sin riktig. Dette skyldes forsinkelsen på 3 sekunder som oppstår når hoved() Funksjonen går ut av sløyfen.
Imidlertid, hvis utførelsestidene til en tråd er lengre enn for hoved() funksjon og det utføres fullt ut, programmet slutter og alle tråder som ble opprettet og fremdeles utfører en oppgave, er automatisk lukket.

La oss se hva som skjer i koden for forrige eksempel hvis vi setter en forsinkelse på 1 sekund per syklus i for -løkken til hoved() funksjon og ett av 3 sekunder i trådsløyfen.

Som vist på bildet, hoved() funksjon fullførte de 5 syklusene til den til Loop, mens tråden bare kunne utføre 3 sykluser før programmet stengte.

Å lukke en tråd uten å utføre den kan føre til kritiske problemer i visse tilfeller, da det kan være lagring av brukergenererte data, skrive til et filsystem eller lagringsenhet, eller utføre en annen oppgave på tidspunktet for avslutning.
For å unngå disse problemene, er det viktig å utvikle en mekanisme for å "vente" på at tråden skal fullføre utførelsen før du lukker programmet eller utfører en oppgave. De pthread_join () Funksjonen stopper funksjonen som opprettet tråden til den tråden er ferdig med utførelsen.

De pthread_join () Funksjonen tar to inngangsargumenter. Den første er trådidentifikatoren returnert av pthread_create () funksjon når tråden opprettes og det andre argumentet er pekeren til en variabel som returnerer utgangsstatusen til tråden.

Deretter bruker vi koden fra forrige eksempel, men erstatter til sløyfe av hoved() funksjon med pthread_join () funksjon, som vist nedenfor:

#inkludere
#inkludere
#inkludere
#inkludere
void* thread_function (void* data);
int main ()

pthread_t thread_1;
printf ("Opprette tråden ... \ n");
pthread_create (& thread_1, null, thread_function, null);
pthread_join (tråd_1, null);
retur 0;

/******************************************************** ****************/
void* thread_function (void* n)

for (int a = 0; a!= 5; A ++)

printf ("fra tråden \ n");
søvn (3);

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

I dette tilfellet hoved() Funksjonen vil bare opprette tråden og vente på at den skal fullføre oppgaven, og deretter lukke programmet.

Mulige feil som Pthread_Create () -funksjonen kan generere og hvordan du gjenkjenner dem

De pthread_create () Funksjon kan generere forskjellige feil, fra ugyldige attributtinnstillinger til utilstrekkelige systemressurser for den nye tråden.
Når en funksjon genererer en feil, lagres en numerisk feilidentifikasjonskode i den globale variabelen errno. Denne variabelen og de numeriske definisjonene for hver feil er definert i “Errno.h ”header.
Nedenfor er en beskrivelse av hver feil som kan oppstå når du ringer pthread_create () funksjon og dens numeriske representasjon definert i “Errno.h ”.

Eagain: Det er ingen ressurser tilgjengelig for å lage en annen tråd. Den numeriske representasjonen av denne feilen er 35.

Einval: Attributtkonfigurasjonen i attr er ikke gyldig. Den numeriske representasjonen av denne feilen er 22.

Eperm: Drift ikke tillatt. Denne feilen oppstår når du ikke har tilstrekkelige tillatelser til å angi attributtparametrene i ATT. Den numeriske representasjonen av denne feilen er 1.

Konklusjon

I dette Linux hint artikkel, vi viste deg hvordan du bruker pthread_create () Funksjon for å lage multitasking -programmer med tråder som kjøres parallelt med hovedfunksjonen.

Vi fortalte deg også hvordan du kan samle programmer som bruker tråder riktig fra kommandolinjen.
Vi har også inkludert en spesiell seksjon som forklarer viktigheten av å ta hensyn til utførelsestidene for de opprettede trådene, og vi har lært deg hvordan du synkroniserer trådene med hovedfunksjonen for å oppnå riktig utførelse.