C 20新特性的小細(xì)節(jié)
時間:2021-10-12 15:10:08
手機看文章
掃描二維碼
隨時隨地手機看文章
[導(dǎo)讀]之前我整理過一篇C20新特性的文章全網(wǎng)首發(fā)??!C20新特性全在這一張圖里了,里面提到過latch、barrier和semaphore,但是沒有詳細(xì)介紹過三者的作用和區(qū)別,這里詳細(xì)介紹下。latch這個可能大多數(shù)人都有所了解,這就是我們經(jīng)常會用到的CountDownLatch。用于...
之前我整理過一篇C 20新特性的文章全網(wǎng)首發(fā)??!C 20新特性全在這一張圖里了,里面提到過latch、barrier和semaphore,但是沒有詳細(xì)介紹過三者的作用和區(qū)別,這里詳細(xì)介紹下。
latch
這個可能大多數(shù)人都有所了解,這就是我們經(jīng)常會用到的CountDownLatch。用于使一個線程先阻塞,等待其他線程完成各自的工作后再繼續(xù)執(zhí)行。
CountDownLatch是通過計數(shù)器實現(xiàn),計數(shù)器的初始值為線程的數(shù)量。每當(dāng)一個線程完成了自己的任務(wù)后,計數(shù)器的值就會減1。當(dāng)計數(shù)器值到達(dá)0時,它表示所有的線程已經(jīng)完成了任務(wù),然后等待的線程就可以打斷阻塞去繼續(xù)執(zhí)行任務(wù)。
自己之前實現(xiàn)過一個CountDownLatch,源碼大概這樣:
barrier
許多線程在阻塞點阻塞,當(dāng)?shù)竭_(dá)阻塞點的線程達(dá)到一定數(shù)量時,會執(zhí)行完成的回調(diào),然后解除所有相關(guān)線程的阻塞,然后重置線程計數(shù)器,繼續(xù)開始下一階段的阻塞。
假設(shè)有很多線程并發(fā)執(zhí)行,并在一個循環(huán)中執(zhí)行一些計算。進一步假設(shè)一旦這些計算完成,需要在線程開始其循環(huán)的新迭代之前對結(jié)果進行一些處理。
看以下示例代碼(摘自cppreference):
latch
這個可能大多數(shù)人都有所了解,這就是我們經(jīng)常會用到的CountDownLatch。用于使一個線程先阻塞,等待其他線程完成各自的工作后再繼續(xù)執(zhí)行。
CountDownLatch是通過計數(shù)器實現(xiàn),計數(shù)器的初始值為線程的數(shù)量。每當(dāng)一個線程完成了自己的任務(wù)后,計數(shù)器的值就會減1。當(dāng)計數(shù)器值到達(dá)0時,它表示所有的線程已經(jīng)完成了任務(wù),然后等待的線程就可以打斷阻塞去繼續(xù)執(zhí)行任務(wù)。
自己之前實現(xiàn)過一個CountDownLatch,源碼大概這樣:
CountDownLatch::CountDownLatch(int32_t count) : count_(count) {}
void CountDownLatch::CountDown() {
std::unique_lock<std::mutex> lock(mutex_);
--count_;
if (count_ == 0) {
cv_.notify_all();
}
}
void CountDownLatch::Await(int32_t time_ms) {
std::unique_lock<std::mutex> lock(mutex_);
while (count_ > 0) {
if (time_ms > 0) {
cv_.wait_for(lock, std::chrono::milliseconds(time_ms));
} else {
cv_.wait(lock);
}
}
}
int32_t CountDownLatch::GetCount() const {
std::unique_lock<std::mutex> lock(mutex_);
return count_;
}
barrier
許多線程在阻塞點阻塞,當(dāng)?shù)竭_(dá)阻塞點的線程達(dá)到一定數(shù)量時,會執(zhí)行完成的回調(diào),然后解除所有相關(guān)線程的阻塞,然后重置線程計數(shù)器,繼續(xù)開始下一階段的阻塞。
假設(shè)有很多線程并發(fā)執(zhí)行,并在一個循環(huán)中執(zhí)行一些計算。進一步假設(shè)一旦這些計算完成,需要在線程開始其循環(huán)的新迭代之前對結(jié)果進行一些處理。
看以下示例代碼(摘自cppreference):
#include
#include
#include
#include
#include
int main() {
const auto workers = { "anil", "busara", "carl" };
auto on_completion = []() noexcept {
// locking not needed here
static auto phase = "... done\n" "Cleaning up...\n";
std::cout << phase;
phase = "... done\n";
};
std::barrier sync_point(std::ssize(workers), on_completion);
auto work = [