Ehtomuuttujat ja työntekijämallit
Koordinoi säikeitä std::condition_variablella ja perinteisellä työskentelysäiemallilla.
Ehtomuuttujat ja työntekijämallit on ilmainen C++ Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu C++ Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C++ Academy-kurssilla on yhteensä 4 oppituntia.
Mikä on ehtomuuttuja?
Ehtomuuttujan avulla säie voi odottaa, kunnes toinen säie ilmoittaa ehdon muuttuneen. Ehtomuuttujia käytetään tuottajien ja kuluttajien koordinointiin.
std::condition_variable-perusteet
Ehtomuuttuja toimii yhdessä std::mutex-olion ja predikaatin kanssa. Odottava säie vapauttaa lukon odottamisen ajaksi ja hankkii sen uudelleen herätessään.
#include <condition_variable>
#include <mutex>
#include <queue>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> tasks;
bool done = false;Ehdon odottaminen
Käyttäkää cv.wait(lock, predicate)-kutsua. Se avaa mutexin lukituksen atomisesti ja nukkuu, kunnes säie herätetään. Herättyään se lukitsee mutexin uudelleen ja tarkistaa predikaatin; jos ehto ei täyty, se jatkaa nukkumista.
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });Ilmoittaminen
Tuottajasäie kutsuu cv.notify_one()- tai cv.notify_all()-funktiota tilan muuttamisen jälkeen. Lukon tulee olla pidettynä tilan muuttamisen ajan.
{
std::lock_guard<std::mutex> lock(mtx);
tasks.push(42);
}
cv.notify_one();Tuottaja–kuluttaja-malli
Klassinen esimerkki: tuottajat lisäävät tehtäviä jonoon ja kuluttajat odottavat tehtäviä.
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });
if (done && tasks.empty()) break;
int task = tasks.front();
tasks.pop();
lock.unlock();
process(task);
}
}Virheelliset heräämiset
Ehtomuuttujaa odottava säie voi herätä ilman ilmoitusta. Siksi wait ottaa predikaatin — se tarkistaa ehdon uudelleen jokaisen heräämisen yhteydessä.
notify_one vs notify_all
Käyttäkää notify_one-funktiota, kun yksi odottaja voi jatkaa etenemistä. Käyttäkää notify_all-funktiota, kun tilan muutos vaikuttaa kaikkiin odottajiin (esimerkiksi sammutussignaali).
Ajastetut odotukset
wait_for(lock, duration) ja wait_until(lock, time_point) herättävät joko ilmoituksen saapuessa tai aikakatkaisun jälkeen.
if (cv.wait_for(lock, 1s, [] { return ready; })) {
/* condition met */
} else {
/* timed out */
}Työtekijäpoolin runko
Yleinen malli: kiinteä joukko työtekijäsäikeitä noutaa tehtäviä jaetusta jonosta. Rakentamiseen tarvitaan mutex, condition_variable, queue ja atominen pysäytyslippu.
Kadonneiden heräämisten välttäminen
Muuttakaa jaettua tilaa ja kutsukaa notify_*-funktiota aina mutexin ollessa pidettynä tilan muutoksen ajan (lukon vapauttaminen juuri ennen ilmoitusta on sallittua, kunhan järjestys varmistetaan). Muuten odottaja voi jäädä ilman ilmoitusta.
std::counting_semaphore (C++20)
Yksinkertaiseen laskentaan perustuvaan signalointiin C++20 lisäsi std::counting_semaphore-luokan — se on joissakin malleissa ehtomuuttujia yksinkertaisempi.
Varokaa lukkiutumista
Useiden lukkojen pitäminen ehtomuuttujaa odotettaessa voi johtaa lukkiutumiseen. Hankkikaa lukot aina yhdenmukaisessa järjestyksessä ja käyttäkää useille mutex-olioille std::scoped_lock-luokkaa.
Pikatarkistus
Miksi cv.wait(lock, predicate) ottaa predikaatin, vaikka haluatte vain odottaa ilmoitusta?
Kertaus
Ehtomuuttuja koordinoi tilan muutosta odottavia säikeitä. Käyttäkää wait(lock, predicate)-kutsua virheellisten heräämisten käsittelyyn, muuttakaa tilaa mutexin suojassa ja kutsukaa sen jälkeen notify_one- tai notify_all-funktiota.
Opi C++ tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 51
- Oppitunnit
- 203
Usein kysytyt kysymykset
Onko oppitunti ”Ehtomuuttujat ja työntekijämallit” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa C++ Academy-oppimispolun 3 oppituntia, myös oppitunnin “Ehtomuuttujat ja työntekijämallit”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. C++ Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Ehtomuuttujat ja työntekijämallit”?
Koordinoi säikeitä std::condition_variablella ja perinteisellä työskentelysäiemallilla. Harjoittelet C++ Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C++ Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C++ Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.
Kuinka kauan ”Ehtomuuttujat ja työntekijämallit”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C++ Academy-oppitunnilla?
Kyllä. Jokainen C++ Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- std::thread: liittyminen ja irrottaminen
- std::mutex, lock_guard ja unique_lock
- Ehtomuuttujat ja työntekijämallit
- std::async- ja std::future-perusteet