DYKP头像
Linux 学习笔记(三十七):System V IPC 进阶——用建造者与责任链模式重构底层接口封面图

Linux 学习笔记(三十七):System V IPC 进阶——用建造者与责任链模式重构底层接口

📌 核心结论(TL;DR):

  1. System V 缺陷:接口(semget/msgget)极其反人类,且生命周期随内核,不手动删就会导致资源泄漏。

  2. 信号量(Semaphore):本质是一个计数器。P 操作(申请资源,减1),V 操作(释放资源,加1)。使用建造者模式(Builder)可以优雅地初始化信号量集合。

  3. 消息队列(Message Queue):支持带“类型”的数据块(实现优先级)。使用责任链模式(Chain of Responsibility)可以流水线式处理消息(格式化 -> 落盘 -> 备份)。

  4. 清理命令:ipcs -s / ipcs -q 查看,ipcrm -s <id> / ipcrm -q <id> 手动删除。

一、 为什么需要设计模式?

原生的 System V IPC 接口(如 semctl 中的 union semun 构造)非常繁琐。如果在业务代码里直接调用,会导致代码极其臃肿。我们利用经典的设计模式对这些系统调用进行二次封装。

二、 信号量:基于建造者模式封装

信号量(Semaphore)用于多进程/多线程间的同步与互斥。因为它涉及的参数较多(Key生成、创建标志、初始值设定),这里引入建造者模式。

// 核心思想:链式调用,最后 Build 出对象
class SemaphoreBuilder {
public:
    SemaphoreBuilder& SetVal(int val) { _val = val; return *this; }
    sem_sptr Build(int flag) {
        // 内部完成 ftok, semget, semctl 的初始化
        // ...
        return std::make_shared<Semaphore>(semid, flag);
    }
};

// 使用方式极其优雅:
SemaphoreBuilder sb;
auto fsem = sb.SetVal(1).Build(BUILD_SEM); 
fsem->P(); // 加锁
fsem->V(); // 解锁

三、 消息队列:基于责任链模式封装

消息队列允许进程发送带有 mtype(类型)的数据块。假设我们有这样一个需求:客户端发来消息,我们需要依次经过“拼接时间格式化” -> “写入文件持久化” -> “判断文件大小,过大则打包备份”。
用 if-else 写会很乱,引入责任链模式(Chain of Responsibility)。

// 1. 抽象处理者
class HandlerText {
public:
    void SetNextHandler(std::shared_ptr<HandlerText> handler) { _next_handler = handler; }
    virtual void Execute(std::string &info) = 0;
protected:
    std::shared_ptr<HandlerText> _next_handler;
};

// 2. 具体处理者:格式化
class HandlerTextFormat : public HandlerText {
    void Execute(std::string &info) override {
        // 处理逻辑:拼接时间
        info = time_str + info; 
        if (_next_handler) _next_handler->Execute(info); // 交给下一个节点
    }
};

// 3. 具体处理者:写文件
class HandlerTextSaveFile : public HandlerText {
    void Execute(std::string &info) override {
        // 处理逻辑:写文件
        if (_next_handler) _next_handler->Execute(info);
    }
};

// 4. 组装责任链
_format->SetNextHandler(_save);
_save->SetNextHandler(_backup);
_format->Execute(msg); // 只要触发头部,整个流水线就会自动跑起来

四、 避坑指南:资源清理

System V IPC 对象(共享内存、消息队列、信号量)的生命周期随内核。即使创建它们的进程崩溃了,资源也会一直留在系统里。

ipcs -q  # 查看消息队列
ipcs -s  # 查看信号量
ipcrm -q <msqid> # 删除指定的消息队列

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/weixin_54085376/article/details/168979547

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--