当年写并发。
你最常写的不是算法。
是同步。
谁先开始。
谁先结束。
一次能进来几个。
这些东西写不好。
线上就会啪一下。
当年:条件变量是万能钥匙,但也挺重
你想等一组线程都准备好。
你就得手搓一个计数器。
再配一把 mutex。
再配一个 condition_variable。
能做。
但每次都要写一遍。
而且很容易漏。
线上啪一下:启动顺序错了,偶发崩溃
你写了个小服务。
主线程启动 N 个 worker。
然后立刻开始分发任务。
有时 worker 还没准备好。
任务就已经来了。
偶发崩溃。
你一看。
就是“少等了一下”。
latch:一次性的“等大家都到齐”
std::latch 就是为这种场景来的。
#include <latch>
#include <thread>
std::latch ready(3);
void worker() {
// init...
ready.count_down();
ready.wait();
// start work...
}
count_down() 表示我准备好了。
wait() 表示我等别人也准备好。
它是一次性的。
计数归零后就结束。
barrier:分阶段的“大家一起往前走”
有些任务不是一次集合。
而是每一轮都要集合一次。
比如分阶段计算。
#include <barrier>
std::barrier sync_point(3);
void step() {
// phase 1...
sync_point.arrive_and_wait();
// phase 2...
}
它的味道很像。
“这一轮都做完了再进入下一轮”。
semaphore:限制并发数量
你有一个资源池。
比如只能同时开 8 个连接。
以前你会用计数器+锁。
现在可以用信号量。
#include <semaphore>
std::counting_semaphore<8> slots(8);
void use_resource() {
slots.acquire();
// use...
slots.release();
}
它表达的就是。
“最多允许 N 个线程同时进入”。
关键结论
同步不是花活。
同步是工程里的常态。
小结
条件变量还是能做一切。
但 latch/barrier/semaphore 让你少写一堆手工样板。
也少踩一堆同步小坑。