For at det er behov for å bli med, er det nødvendig med to tråder. Den ene tråden kaller den andre tråden. Å bli sammen med en tråd betyr at mens den ringte tråden kjører, vil den stoppe i en stilling og vente på at den kalte tråden skal fullføre utførelsen (til slutt), før den fortsetter sin egen utførelse. I den posisjonen der tråden stopper, er det et sammenføyningsuttrykk. Slik stopp kalles blokkering.
Hvis den kalte tråden tar for lang tid å fullføre og sannsynligvis har gjort det som den samtaletråden forventet at den skulle gjøre, kan den anropende tråden løsne den. Etter å ha løsnet, hvis den kalte tråden er fullført etter ringetråden, skal det ikke være noe problem. Å løsrive betyr å bryte sammen med (lenke).
Minnes
En tråd er en toppnivåfunksjon som har blitt innelukket i et trådobjekt, instantiert fra trådklassen. Instortering av tråden med toppnivåfunksjonen betyr å kalle funksjonen. Her er et enkelt trådprogram, med Join -uttalelsen:
#inkludere
#inkludere
ved hjelp av navneområdet STD;
void func ()
cout <<"… from thread!" <<'\n';
int main ()
tråd THD (func);
thd.bli med();
/ * uttalelser */
retur 0;
Det er to tråder her: Objekt, THD og hovedfunksjonen (). Hovedfunksjonen er som hovedtråden. Legg merke til inkludering av trådbiblioteket. Utgangen er:
... fra tråd!
På ledeteksten bør et C ++ 20 -program med tråder, kommanderes som følger, for G ++ -kompilatoren:
G ++ -STD = C ++ 2A prøve.cc -lpthread -o prøve.EXE
Artikkelinnhold
løsne () syntaks
Syntaks () Syntax er enkel; Det er:
ThreadObject.løsne()
Denne medlemsfunksjonen til trådobjektet returnerer tomrom. ThreadObject er trådobjektet til tråden hvis funksjon kjører. Når funksjonen til en tråd kjører, kalles tråden den utførende tråden.
En tråd kan bare løsnes etter at den er blitt sammen; Ellers er tråden allerede i frittliggende tilstand.
Tvetydighet ved å løsrive seg i den anropende trådens kropp
I det følgende programmet er den kalt tråden løsrevet i kroppen av den samtaletrinnen:
#inkludere
#inkludere
#inkludere
ved hjelp av navneområdet STD;
Streng globl = streng ("på jorden!");
void func (streng st)
String fin = "Living" + ST;
cout <
int main ()
Tråd Thr (Func, Globl);
thr.bli med();
thr.løsne();
retur 0;
Utgangen fra forfatterens datamaskin ved kjøretid var:
Bor på jorden!
Avslutt kalt etter å ha kastet en forekomst av 'std :: System_error'
hva (): ugyldig argument
Abortert (kjernen dumpet)
Riktig forventet produksjon skal være bare:
Bor på jorden!
Når en tråd avslutter utførelsen, frigjør implementeringen alle ressursene den eide. Når en tråd er forbundet, venter kroppen til den samtalede tråden på det punktet til den kalt tråden fullfører utførelsen, deretter fortsetter kroppen av den samtaletråden sin egen utførelse.
Problemet med tilstedeværelsen av den videre produksjonen er at selv om den kalt tråden kan ha fullført oppgaven gitt den, hadde ressursene ikke alle blitt tatt bort, men Full () -funksjonen fikk kroppen til å ringe funksjonen til å fortsette å utføre. I mangel av løsne () -funksjonen, ville den kalt tråden ha fullført, pluss alle ressursene tatt bort; Og utgangen ville ha vært den enkle en-linjen forventet.
For å overbevise leseren videre, bør du vurdere følgende program, som er det samme som det ovennevnte, men med uttalelsene med Join () og løsne () kommentert:
#inkludere
#inkludere
#inkludere
ved hjelp av navneområdet STD;
Streng globl = streng ("på jorden!");
void func (streng st)
String fin = "Living" + ST;
cout <
int main ()
Tråd Thr (Func, Globl);
// thr.bli med();
// thr.løsne();
retur 0;
Utgangen fra forfatterens datamaskin er:
avsluttet kalt uten et aktivt unntak
Abortert (kjernen dumpet)
Hoved () -funksjonen løp gjennom til enden uten å vente på at tråden skulle gjøre noe. Og slik kunne ikke tråden vise utgangen.
Trådnavn i globalt omfang
En tråd kan bli instantiert med globalt omfang. Følgende program illustrerer dette:
#inkludere
#inkludere
ved hjelp av navneområdet STD;
tråd thr;
void func ()
cout <<"the first line" <cout <<"the second line" <
int main ()
thr = tråd (func);
thr.bli med();
retur 0;
Utgangen er:
den første linjen
den andre linjen
Før funksjonen er func () definert i programmet; Det er uttalelsen,
tråd thr;
som instantierer tråden, thr. På dette tidspunktet har THR ikke en tilsvarende funksjon. I hovedfunksjonen () er den første uttalelsen:
thr = tråd (func);
Høyre side av denne uttalelsen oppretter en tråd uten navn og tildeler tråden til trådvariabelen, THR. På denne måten skaffer THR en funksjon. Neste uttalelse blir med den kalte tråden.
Løsning innen den kalte tråden
En bedre måte å løsne en tråd på er å gjøre det i kroppen til den kalt tråden. I dette tilfellet må trådobjektet opprettes i det globale omfanget, som illustrert ovenfor. Da vil løsningen på løsningen være i kroppen til den kalt tråden, hvor løsringen skal finne sted. Følgende program illustrerer dette:
#inkludere
#inkludere
ved hjelp av navneområdet STD;
tråd thr;
void func ()
cout <<"the first line" <thr.løsne();
cout <<"the second line" <
int main ()
thr = tråd (func);
thr.bli med();
cout <<"main() function line" <retur 0;
Utgangen er:
den første linjen
den andre linjen
Main () Funksjonslinje
Ingen feilmeldinger ble utstedt ved kjøretid. Uttalelsen av Join () forventet at tråden skulle utføre før hovedkroppen () kunne fortsette. Det skjedde til tross for at den kalt tråden ble løsrevet midt i utførelsen, med uttalelsen,
thr.løsne();
Og så fortsatte hovedtråden (hovedtråden) etter at den kalte tråden hadde fullført, med alle ressursene som ble gitt ut av implementeringen. I andre halvdel av den kalte tråden var den kalt tråden allerede løsrevet, selv om den samtaletråden fremdeles ventet.
Programmet begynner med inkludering av iostream -biblioteket for cout -objektet. Deretter er det inkludering av trådbiblioteket, som er et must. Så er det oppstart av tråden, THR, uten en funksjon. Funksjonen den vil bruke er definert like etter. Denne funksjonen har den løsrevne uttalelsen av objektet, THR i kroppen.
I hovedkroppen () oppretter den første uttalelsen en tråd av en funksjon, men uten navn. Denne tråden blir deretter tildelt THR. Så THR har nå en funksjon, med fordelen som den ble opprettet i det globale omfanget, slik at den kunne sees i Func ().
Neste uttalelse blir med i funksjonen for hovedfunksjonen () til den kalt tråden. Tråden ble kalt i den første uttalelsen av Main () -funksjonen. På dette tidspunktet venter hovedkroppen () funksjonen på at den kalte tråden skal løpe til slutt og alle ressursene som ble frigjort, selv om den ble løsrevet i midten. Join () -funksjonen gjør sin plikt så lenge alt inne i den kalt tråden er legitim.
Og derfor fortsetter utførelsen med hovedfunksjonen etter at den kalte tråden har forlatt vellykket, som forventet (med alle ressursene som er utgitt). Det er hvorfor,
“Main () funksjonslinje”
sendes ut etter alle utgangene fra den kalt tråden.
Konklusjon
Å løsne en tråd betyr at den kalt tråden kan fortsette å utføre, mens tråden kalte den også kan fortsette å utføre. Det vil si at den anropstråden ikke lenger fortsetter å vente (blokkering), etter at han ble med. Dette kan øke hastigheten på begge trådene, slik at de kan løpe parallelt og øke hastigheten på hele programmet. I dette tilfellet er det best å løsne tråden i kroppen, der kommunikasjon mellom dem ikke lenger vil oppstå. For å oppnå dette, la trådvariabelen opprettes i det globale omfanget uten dens funksjon. I hovedfunksjonen for C ++ -programmet kan en anonym tråd, med funksjonen av interesse, opprettes og tilordnes trådvariabelen. Dette trinnet kaller trådfunksjonen, og ringer slik tråden.
Så etter den frittliggende uttalelsen har ikke uttalelsen om Join (). Det anbefales ikke å løsne den kalte tråden fra anroptråden.