ZLToolKit 源码分析(二):线程同步原语 semaphore 与 onceToken
高并发框架的基石是同步原语。本文逐行分析 ZLToolKit 自研的 semaphore(信号量)和 onceToken(RAII 守卫),揭示其如何用 C++11 标准库实现高效且安全的线程同步。1. 为什么不用 std::semaphore?C++20 才引入std::counting_semaphore,而 ZLToolKit 基于 C++11 开发,必须自研。其实现基于std::condition_variable+std::mutex,语义等价于std::counting_semaphore。2. semaphore 源码全解文件:src/Thread/semaphore.h2.1 完整源码classsemaphore{public:semaphore(size_t initial=0){_count=initial;}// V 操作:释放信号量voidpost(size_t n=1){std::lock_guardstd::mutexlock(_mutex);_count+=n;if(n1){_condition.notify_all();}else{_condition.notify_one();}}// P 操作:获取信号量(阻塞)voidwait(){std::unique_lockstd::mutexlock(_mutex);while(_count==0){_condition.wait(lock);}--_count;}private:size_t _count;std::mutex _mutex;std::condition_variable _condition;};2.2 逐行精析post() — 释放信号量voidpost(size_t n=1){std::lock_guardstd::mutexlock(_mutex);// RAII 加锁_count+=n;// 增加计数if(n1){_condition.notify_all();// 释放多个,唤醒所有等待者}else{_condition.notify_one();// 释放一个,只唤醒一个}}关键设计:n 1时用notify_all()——因为多个等待者可能都需要被唤醒n == 1时用notify_one()——避免惊群效应(thundering herd)wait() — 获取信号量voidwait(){