Мазмунга өтүү

Параллелдик паттерндер: агым пулдары жана "өндүрүүчү-керектөөчү" маселеси

Сабактын башталышы

Параллелдик паттерндер: агым пулдары жана "өндүрүүчү-керектөөчү" маселеси

Жөнөкөй агымдардан кайра колдонулуучу, кулпуланбаган конструкцияларга чейин

Негизги идея: Сиз мурунтан эле std::thread ишке киргизүүнү, std::mutex менен жалпы маалыматты коргоону жана атомдук операциялар аркылуу эстек моделин түшүнүүнү билесиз. Булар примитивдер. Чыныгы системалар сейрек гана ар бир тапшырмага бир агым түзөт жана ар бир чакырууда синхрондоштурууну кол менен жазбайт. Анын ордуна алар бир нече кайра колдонулуучу паттерндерди чогултушат: белгиленген жумушчу агымдар топтомуна ээ агым пулу, алардын ортосунда ишти өткөрүп берген агым-коопсуз кезек, жана std::condition_variable үстүнө курулган өндүрүүчү-керектөөчү кол алышуу. Ушул үчөөнү өздөштүрсөңүз, агымдарды жоготпой, активдүү күтпөй жана жалпы маалыматка кагылышуу түзбөй, дээрлик каалаган параллелдик конвейерди кура аласыз.
Аягында сиз төмөнкүлөрдү жасай аласыз:
  • эмне үчүн ар бир тапшырмага бир агым масштабдалбай турганын жана агым пулу муну кантип чечерин түшүндүрүү;
  • std::mutex жана std::condition_variable менен чектелген агым-коопсуз кезек куруу;
  • туура кулпулоо жана ойготуу менен "өндүрүүчү-керектөөчү" паттернин ишке ашыруу;
  • тапшырмаларды кабыл алып, std::future кайтарган кичине агым пулун чогултуу;
  • классикалык коркунучтарды таануу жана алдын алуу: жоготулган жана жалган ойготуулар, өз ара кулпулоолор жана маалымат кагылышуулары.

1. Эмне үчүн ар бир тапшырмага бир агым эмес?

Параллелизмге карата жөнөкөй ыкма мындай: ар бир иш бирдиги үчүн std::thread(doWork) чакыруу. Аны жазуу оңой жана масштабдаганда дээрлик дайыма туура эмес. Агымдар акысыз эмес:

  • Түзүү наркы: ОС агымын пайда кылуу микросекунддарды жана өзүнчө стекти талап кылат (көбүнчө 1 МБ резервделет). Ар бир суроого агым түзгөн иштетүүчү муну кайра-кайра төлөйт.
  • Ашыкча жазылуу (oversubscription): эгер 8 ядролуу машинада 10 000 тапшырма ар бири бир агым түзсө, планировщик ядролордон алда канча көп агымдардын ортосунда контекстти которуштуруп такалат, жана өткөрүмдүүлүк төмөндөйт.
  • Чектелбеген ресурс колдонуу: агымдардын санын эч нерсе чектебейт, ошондуктан иштин күтүлбөгөн көбөйүшү эстекти же ОС дескрипторлорун түгөтүшү мүмкүн.

Агым пулу бул байланышты тескери айландырат. Ал бир жолу белгиленген сандагы узак жашаган жумушчу агымдарды түзөт (адатта std::thread::hardware_concurrency()), андан кийин аларга жалпы кезек аркылуу кичине тапшырмалардын агымын берет. Жумушчу агымдар циклде айланат: тапшырманы алат, аткарат, кайталайт. Агымдар кайра колдонулат, алардын саны чектелген, ал эми кезек табигый түрдө күтүлбөгөн көбөйүүлөрдү жумшартат. Бул дээрлик ар бир сервердин, агымга негизделген асинхрондук чөйрөнүн жана параллелдик алгоритм китепканасынын паттерни.

Ой жүгүртүүдөгү жылыш: "агым бул тапшырма" деп ойлоону токтотуп, "агым — бул тапшырмаларды керектеген жумушчу" деп ойлой баштаңыз. Тапшырмалар маалыматка айланат; агымдар белгиленген инфраструктурага айланат.

Бул сабакты YourAIZone платформасында улантыңыз

Толук сабакта — толук түшүндүрмө, чыгарылган мисалдар, көп кездешкен каталар, заматта текшерилүүчү тесттер жана ЖИ-репетитор. Конок катары дароо баштаңыз же прогрессти сактоо үчүн аккаунт түзүңүз.

Толук сабакта

  • Толук түшүндүрмө
  • Чыгарылган мисалдар
  • Көп кездешкен каталар жана алардан кантип качуу керек
  • Тест суроолору: 15
  • Тема боюнча суроолорго жооп берген ЖИ-репетитор
  • Окуучу, ата-эне жана мугалим үчүн прогрессти көзөмөлдөө