2021-08-26

C++ Latch 实现

Views: 15170 | Add Comments

Latch(Binary Semaphore) 不同于信号量(Counting Semaphore), 也不同于条件变量, 它是一种合并信号成一个标记的通信方式, 可用于实现 Batch 操作. 例如, 两个线程围绕一个标记, 一个设置(生产者), 一个复位(消费者). 如果标记已设置, 则消费者立即复位然后返回. 如果标记未设置, 则消费者等待标记被设置.

在生产者消费者编程模式中, 生产者产生任务, 任务被加入队列中, 同时通过 Latch 告知消费者. 使用 Latch 的话, 可能多个任务产生之后, 消费者才会获知消息, 于是, 便可以将多个任务合并处理, 也即所谓的 Batch(批量)操作. 同时, 只要有任务, 标记就一定会被设置, 消费者不会漏掉任务.

如果使用条件变量, 那么消费者可能漏消息. 因为, 如果消费者在忙于处理任务时, 生产者的通知将会被丢弃.

如果使用信号量, 那么消费者进行 Batch 操作之后, 后续的堆积的信号会导致空操作, 因为任务已经处理完了, 但信号还在.

所以, Latch 是一种非常有用的数据结构.

class Latch
{
private:
    std::mutex mux;
    std::condition_variable cv;
    bool flag = false;

public:
    void wait(){
        std::unique_lock<std::mutex> lock(this->mux);
        while(!this->flag){
            this->cv.wait(lock);
        }
        this->flag = false;
    }

    void notify(){
        {
            std::unique_lock<std::mutex> lock(this->mux);
            this->flag = true;
        }
        this->cv.notify_one();
    }
};

Golang 版本: https://github.com/ssdb-cluster/base/blob/master/util/latch.go

Related posts:

  1. 生产者消费者模型中生产者的速度快于消费者时所产生的问题及其解决方法讨论
  2. 必须放在循环中的pthread_cond_wait
  3. C#环形缓冲
  4. C# 中实现 FIFO 缓冲区–ArrayBuffer
  5. CSS 样式规则的匹配算法实现
Posted by ideawu at 2021-08-26 21:10:33

Leave a Comment