共享内存实现多进程低延迟队列 10us

起因

之前的博客写过通过inotify 加文件的形式来实现多进程队列的文章。这种方式在通常情况下表现不错,但是这里存在一个问题就是当消费者过慢,会产生大量的击穿内核高速缓冲区io,导致消费者卡在读取数据的瓶颈上,无法使用负载均衡等手段来提高处理能力。

为了解决上述问题,引入了共享内存,众所周知,这是所有ipc中最快的通信方式,从根本上解决这个问题。下面通过实现一个producer 和 consumer 程序,来展示我的设计思路。

 

producer

由于物理内存有限,生产者会使用一个环形缓冲区来保证热点数据始终在内存中。同时为了保证消费者的接入配置最小化,生产者将配置通过一个固定大小的结构体映射到内存中,消费者首先映射结构体读取配置信息,从结构体中的得知缓冲区大小后执行mremap进行重新调整大小,这样消费者只需要知道共享内存的地址(一个文件名),就可以实现消费。同时采用了消息计数,来标识消费者是否已经处理所有消息,触发等待。当消费者在等待新数据时,唤醒消费者我们选择了通过向指定文件写入一个字节的内容触发inotify,虽然通过信号量也可以实现,但是使用信号量会导致生产者要多开一个线程实现管理,引入额外的复杂度。

#include <sys/stat.h>
#include <fcntl.h>
#include <sys/inotify.h>
#include <functional>
#include <unistd.h>
#include <cstring>
#include <string>
#include <sys/mman.h>
#include <sys/time.h>
#include <iostream>
#include <semaphore.h>

#include <gflags/gflags.h>

DEFINE_int64(shm_size, 6, "shm_size m");
DEFINE_string(inotify_file, "/tmp/writer.txt", "inotify file path");
DEFINE_string(shm_file, "/test", "shm file path");
DEFINE_string(shm_key, "", "shm key");

class Producer
{
public:
    Producer(const std::string &inotify_path, const std::string &shm_path) : inotify_path_(inotify_path), shm_path_(shm_path)
    {
        shm_size_ = FLAGS_shm_size * 1024 * 1024; // 1g; // 1g
    }

    bool Init(const std::string &key)
    {
        fd_ = open(inotify_path_.c_str(), O_WRONLY | O_APPEND | O_CRE
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值