Көп агымдуулук
Кодду коопсуз параллель аткаруу: агымдар, мьютекстер, шарттуу өзгөрмөлөр жана өз ара бөгөттөөдөн качуу
pthreads же Win32 агымдары сыяктуу платформага байланыштуу API'лер мындан ары керек эмес.
- ишти
std::threadто баштоо жана анын жашоо мөөнөтүнjoin/detachаркылуу башкаруу - жана C++20дунstd::jthreadин артык көрүү; - маалымат жарышы деген эмне жана эмне үчүн ал аныкталбаган жүрүм-турум экенин түшүндүрүү;
- жалпы абалды
std::mutexжана RAII кайтаргычтарыlock_guardмененunique_lockаркылуу коргоо; - агымдарды
std::condition_variableаркылуу предикат менен күтүү идиомасын колдонуп координациялоо; - өз ара бөгөттөөнү (deadlock) таануу жана кулпулоо тартиби менен
std::scoped_lockаркылуу андан качуу.
1. Конкуренттүүлүк жана параллелизм, жана std::thread
Конкуренттүүлүк - бул түзүлүш касиети: бир нече тапшырма кайчылашкан убакыт аралыгында иштеп жатат. Параллелизм - бул аткаруу касиети: тапшырмалар түз эле бир учурда ар башка ядролордо иштейт. Агымдар конкуренттүүлүктү туюнтууга мүмкүндүк берет; ал чыныгы параллелизмге айланабы - бул аппараттан көз каранды. Жеткиликтүү ядролордун санына кеңеш катары std::thread::hardware_concurrency() колдонуңуз.
std::thread (<thread>тен) өзүнүн чакырылуучу объектин конструкциялоодо дароо аткара баштайт. Сиз каалаган чакырылуучу объектти - функцияга көрсөткүчтү, лямбданы, функторду - плюс анын аргументтерин бересиз. Аргументтер демейде агымга көчүрүлөт; шилтеме менен берүү үчүн аларды std::refке ороп коюңуз.
#include <thread>
#include <iostream>
void greet(int id) { std::cout << "hello from " << id << "\n"; }
int main() {
std::thread t(greet, 42); // азыр иштей баштайт
t.join(); // бүткөнүн күтөбүз
}
std::thread жок кылынганга чейин анын тагдырын чечишиңиз керек: join() агым бүткөнгө чейин бөгөттөйт, ал эми detach() аны көз карандысыз иштеткенге коё берип, дескрипторуңузду үзөт. Эгер кошула турган (joinable) агымды экөөнүн бирин да жасабай жок кылсаңыз, деструктор std::terminate() чакырат жана программа үзгүлтүккө учурайт. Бул катаал эреже сиз кокусунан иштеп жаткан агымды жоготуп жибербеш үчүн бар.
std::jthread. jthread ("кошулуучу агым") бул тузакты оңдойт: анын деструктору автоматтык түрдө join жасайт, ошондуктан унутулган join мындан ары программаны токтотпойт. Ал ошондой эле std::stop_token алып жүрөт, ошентип агымдан кооперативдүү токтоону сураса болот. Жаңы C++20 кодунда std::jthreadти артык көрүңүз.