Úvod do std::latch v C++
V moderním programování je paralelismus a synchronizace klíčovým aspektem pro efektivní využití vícevláknových aplikací. S příchodem standardu C++20 byla do jazyka přidána řada užitečných nástrojů pro práci s více vlákny. Jedním z těchto nástrojů je synchronizační primitivum std::latch. Tento článek vám představí, co je std::latch, jak funguje a jak jej můžete využít ve svých projektech.
Co je std::latch?
std::latch je synchronizační mechanismus, který umožňuje vláknu čekat, dokud určitý počet událostí není dokončen. Na rozdíl od jiných synchronizačních primitiv, jako je například std::barrier, je std::latch jednorázový – jakmile je dosaženo nulového počtu, nelze jej znovu použít.
Hlavní vlastnosti std::latch:
- Jednorázový mechanismus: Po dosažení nulového počtu nelze
std::latchresetovat. - Počítání událostí: Umožňuje snížit interní čítač o jednu jednotku při každém zavolání metody
count_down. - Blokování vláken: Vlákna mohou čekat na dosažení nulového počtu pomocí metody
wait.
Jak std::latch funguje?
Při vytvoření instance std::latch je inicializován čítač s určitou hodnotou. Tato hodnota reprezentuje počet událostí, které musí být dokončeny, aby se vlákna mohla odblokovat. Každé zavolání metody count_down sníží čítač o 1. Jakmile čítač dosáhne nuly, všechna čekající vlákna se odblokují.
Příklad použití
Níže je ukázkový příklad, jak lze std::latch použít pro synchronizaci vláken:
#include <iostream>
#include <thread>
#include <latch>
#include <vector>
void worker(std::latch& latch, int id) {
std::cout << "Vlákno " << id << " pracuje...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // Simulace práce
std::cout << "Vlákno " << id << " dokončilo práci.\n";
latch.count_down(); // Snížení čítače
}
int main() {
const int num_threads = 5;
std::latch latch(num_threads); // Inicializace latch s počtem vláken
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i) {
threads.emplace_back(worker, std::ref(latch), i);
}
latch.wait(); // Čekání na dokončení všech vláken
std::cout << "Všechna vlákna dokončila práci.\n";
for (auto& t : threads) {
t.join();
}
return 0;
}
Vysvětlení kódu
- Inicializace
std::latch: Vytvořímestd::latchs počáteční hodnotou odpovídající počtu vláken. - Práce vláken: Každé vlákno provede svou práci a poté zavolá
count_down, čímž sníží čítač. - Čekání na dokončení: Hlavní vlákno zavolá
wait, aby počkalo, dokud čítač nedosáhne nuly. - Dokončení: Jakmile všechna vlákna dokončí práci, hlavní vlákno pokračuje.
Kdy použít std::latch?
std::latch je užitečný v situacích, kdy potřebujete zajistit, že určitý počet úkolů nebo vláken dokončí svou práci předtím, než bude pokračovat další část programu. Typické scénáře zahrnují:
- Inicializaci více vláken před spuštěním hlavní logiky.
- Synchronizaci mezi různými částmi programu, které musí být dokončeny v určitém pořadí.
Závěr
std::latch je jednoduchý, ale mocný nástroj pro synchronizaci vláken v C++. Díky jeho přehlednému API a podpoře v moderním standardu C++20 je ideální volbou pro jednorázové synchronizační úkoly. Pokud pracujete na vícevláknových aplikacích, určitě stojí za to se s tímto nástrojem seznámit a začlenit jej do svých projektů.