Linux IPC:共享内存回收

2024-03-27

我有两个进程(生产者和消费者)通过使用生成的共享内存段进行通信'old' https://stackoverflow.com/questions/21311080/linux-shared-memory-shmget-vs-mmap接口而不是 mmap:

auto key = ftok(<somefile>,<someid>;
int ret = shmget(key, size, flags);
void* memArea = shmat(key,NULL,0);
// check errors and do stuff...

生产者进程可能会由于错误或配置更改而重新启动。 它每次使用 shmget() 的 IPC_CREAT 标志创建一个新区域。 我注意到消费者可以继续从现有的共享内存段中读取数据,而替换生产者已转移到另一个共享内存段。

消费者进程如何检测并从中恢复?


改变你的生产者设计可能是更好的主意:

  • 它可以首先检查是否存在可以重用的现有段,而不是使用 IPC_CREAT。

  • 您还可以考虑使用基于 mmap 的共享内存,这在某些方面更灵活。

  • 您可以使用其他一些指标(例如锁定文件)来确定共享内存接口是否仍然可行。

但是,如果由于某种原因这些不是选项(例如其他人控制生产者代码),那么请继续阅读。

您可以执行以下几项操作:

  1. use shmctl https://linux.die.net/man/2/shmctl() 来“统计”你的内存段
 // return true if the shared memory region is still 'useful/useable'
 bool checkShm(int shmId)
 {
     struct shmid_ds statBuf;
     int res = shmctl(<shmid>, IPC_STAT, statBuf);
     if (res == -1) return false;
     ...
  1. 检查该区域是否被标记为删除(特定于 Linux)
 if ((statBuf.shm_perm.mode&SHM_DEST) != 0) return false;
  1. 假设您在生产者之后附加,并且它是创建者进程 - 检查它是否在您之后分离。警告:如果您的设计允许,它可能会再次重新连接。
 if (statBuf.shm_cpid == shmBuf.shm_lpid) return false;
  1. 检查创建者进程的 PID 是否是正在运行的进程。警告:PID 可以被新进程回收
 if (getpgid(shmBuf.shm_cpid) == -1) return false;

注意:你可以使用kill(shmBuf.shm_cpid,0)相反,如果生产者不是不同的用户。

  1. 您可能还想检查文件是否已被修改。 一个关键点是ftok 使用 inode 号 https://code.woboq.org/userspace/glibc/sysvipc/ftok.c.html不是实际的文件名man page https://linux.die.net/man/3/ftok建议。所以你需要小心使用它:
struct stat fstatBuf;
int res = stat(fileName,&fstatBuf);
if (res == -1) return false; // if the file has disappeared it could be a bad sign!
if (fstatBuf.st_ino != savedInode) return false;

完成所有这些后,您现在应该有一个相当好的方法来检查您认为仍然有用的 SHM 是否实际上被您认为的“生产者”使用。

  1. 清理陈旧的共享内存段

您现在可以自由地将 shmdt() 从段中分离出来,并尝试清理它 shmctl(shmid,IPC_RMID,NULL)。如果创建者未授予消费者进程可能无权删除它。

  1. 附加到替换共享内存段

然后,原则上您可以附加到由替换生产者进程创建的任何新共享内存段:

auto key = ftok(<somefile>,<someid>;
void* memArea = shmat(key,NULL,0);
// check errors and do stuff...

但残酷而有趣的惩罚正在等待着你。它不会立即起作用。您必须等待一段时间并定期重试。我想这是直到操作系统有机会清理旧的内存段为止。

我发现 ftok() 暂时返回 -1,尽管文件存在并且与原始文件具有相同的 inode。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux IPC:共享内存回收 的相关文章

  • pctl(PR_SET_PDEATHSIG) 竞争条件

    据我了解 当父进程死亡时终止子进程的最佳方法是通过prctl PR SET PDEATHSIG 至少在 Linux 上 父进程退出后如何让子进程终止 https stackoverflow com questions 284325 how
  • 如何从 USB 加载 LUKS 密码,然后返回键盘?

    我想设置一台具有全磁盘加密功能的无头 Linux Debian Wheezy PC 能够使用 USB 驱动器或通过键盘输入密码来解锁磁盘 我的起点是使用 Debian 安装程序中基本的整个磁盘加密选项进行全新安装 该安装程序将 boot 之
  • Linux 中的 C 聊天室 / Socket 编程

    我有一个简单的服务器和客户端 C 代码来使用线程 pthread 库 为多客户端创建一个聊天室 我一直遇到的问题是 我无法想出一种方法让服务器将客户端通过套接字发送到所有其他客户端的每条消息写入 我在这里读过其他类似的帖子 但很无奈 请帮助
  • 服务器启动时 Java 运行时环境 SIGSEGV 错误

    我正在使用 java 版本 1 7 0 45 和 eclipse kepler 在服务器启动时我收到以下错误日志 虽然我发现了几个帖子 1 https stackoverflow com questions 19332489 how to
  • 在 Sublime Text 3 中,我可以将 do 文件的选择发送到 Stata 吗?

    This SO question https stackoverflow com questions 18361667 is there a command line editor that highlights the stata syn
  • 如何禁用浮点单元(FPU)?

    我想在 x86 系统中禁用 FPU MMX SSE 指令 并且我将为设备不可用异常实现一个处理程序 我已经提到过控制寄存器 wiki 页面 http en wikipedia org wiki Control register 看来我必须在
  • 计算以某个单词开头的行数

    如何计算文本文件中以某个单词开头的行数 我不想使用sed进而wc l 有更好的解决办法吗 只需 grep 你的单词 然后使用 wc l 来计算行数 就像这样 grep your word path to file wc l
  • Nvcc 的版本与 CUDA 不同

    我安装了 cuda 7 但是当我点击 nvcc version 时 它打印出 6 5 我想在 GTX 960 卡上安装 Theano 库 但它需要 nvcc 7 0 我尝试重新安装cuda 但它没有更新nvcc 当我运行 apt get i
  • 调试严重的 SIGILL 崩溃:文本段损坏

    我们的系统是基于 PowerPC 的运行 Linux 的嵌入式系统 我们遇到了随机的 SIGILL 崩溃 这种情况在各种应用程序中都会出现 崩溃的根本原因是将要执行的指令归零 这表明内存中的文本段已损坏 由于文本段是以只读方式加载的 因此应
  • Docker 无法写入使用 -v 挂载的目录,除非它有 777 权限

    我正在使用docker solr https github com makuk66 docker solr使用 docker 生成图像 我需要在其中安装一个目录 这是我使用 v flag 问题是容器需要写入我已安装到其中的目录 但似乎没有权
  • find 命令的“exec”功能可以在后台启动程序吗?

    我想做这样的事情 find iname Advanced Linux Program exec kpdf 可能的 还有其他类似的方法吗 首先 它不会像你输入的那样工作 因为 shell 会将其解释为 find iname Advanced
  • Alsa:如何在 2 个输出上复制流并保存系统配置?

    我的声卡是 Audigy SE SB0570 我想不仅在扬声器上而且在耳机上同时播放相同的立体声流 我在空的 asoundrc 上尝试这个配置 pcm quad type multi slaves a pcm hw 0 0 green ho
  • 如何在 Docker 容器中运行 Nginx 而不停止?

    我在 Docker 容器上安装了 Nginx 并尝试像这样运行它 docker run i t p 80 80 mydockerimage usr sbin nginx 问题是 Nginx 的工作方式是 初始进程立即生成一个 Nginx 主
  • Linux命令:如何仅“查找”文本文件?

    经过几次谷歌搜索后 我得出的结论是 find my folder type f exec grep l needle text exec file grep text 这非常不方便 并且会输出不需要的文本 例如 mime 类型信息 还有更好
  • 如何在 Linux 上使用 Python 导出

    我需要在 Python 中进行这样的导出 export MY DATA my export 我尝试过这样做 python mode coding utf 8 import os os system export MY DATA my exp
  • 使用 java.nio.Files 更改 Linux 下的文件所有者组

    我有一台 Linux 服务器 并且正在 Java 中为服务器上的多个网站运行图像调整大小作业 网站文件由不同的操作系统用户 组拥有 新创建的缩略图 预览由运行调整大小作业的用户拥有 现在我正在谷歌搜索如何在调整大小程序中更改新创建的预览 缩
  • 使用curl复制本地文件[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有办法用curl复制本地文件 我需要它作为cp命令的替代品 这有点奇怪 但我正在一个 cp 不可用的环境中工作 你可以说 curl o
  • tar 命令在提取时更改所有者:组

    使用此命令提取文件时tar zxf bluez arm package tgz文件和目录的所有者 1000 组 脉冲 是 更改如下例 Example drwxrwxr x 4 1000 pulse 1024 Jul 21 00 32 dbu
  • 文件在 rpm 规范文件中列出两次

    我的规范文件的文件部分如下所示 files prefix htdocs config prefix htdocs share settings config inc php 现在 由于配置文件已经包含在 prefix htdocs 我收到警
  • Ruby - 在 tmp/pids/thin.pid 中找不到 PID (Thin::PidFileNotFound)

    我试图开始精简我的应用程序 但随后pid无法生成 thin C var www project path current config myproject testing yml start 现在我无法阻止它 因为没有 pid thin C

随机推荐

  • Swift根据数据改变tableviewcell边框颜色

    我已经编写了一个代码 用于根据 inStock 或 outStock 更改单元格边框颜色 如果是 inStock 它将是红色边框 否则它将是绿色 但我它对我不起作用 我将它放在 willDisplayCell 中 这里是我的代码 func
  • MySQL 到 PostgreSQL 表创建转换 - 字符集和排序规则

    我想从 MySQL 迁移到 PostgreSQL 我的创建表查询是这样的 CREATE TABLE IF NOT EXISTS conftype CType char 1 NOT NULL RegEx varchar 300 default
  • 哪个更好/更快:连接许多表或选择一张大表

    我们正在使用 Oracle 11 这是我们用 Java 编写的应用程序 每天一次 通常是下午 我们的数据库由于许多大的 SQL 查询而冻结 我想以某种方式优化这个查询 该查询由不同表的许多联接组成 我的问题是 使用左连接对性能更好 还是将所
  • 流浪者 403 禁止

    我已经成功运行 Vagrant 大约一周了 昨晚我运行了 vagrant reload 现在我无法再访问我的网站 VirtualBox 版本 4 2 16 流浪者版本1 2 7 我的 Vagrantfile 和 bootstrap sh h
  • 当反向关系上 full=True 时,Django Tastypie 会抛出“超出最大递归深度”。

    如果运行以下代码 我会超出最大递归深度 from tastypie import fields utils from tastypie resources import ModelResource from core models impo
  • Presto 和 Impala 之间的基本架构、SQL 合规性和数据使用场景有哪些差异?

    有专家能从这些角度对Presto和Impala的区别给出一些简洁的答案吗 基础架构设计 SQL合规性 现实世界的延迟 任何 SPOF 或容错功能 结构化和非结构化数据使用场景表现 Apache Impala 是仅适用于 HDFS Hive
  • WebElements 列表中的相对 Xpath

    在收集 WebElements 列表后是否可以使用相对 xpath 如果是这样 最好的方法是什么 这就是我所拥有的 List
  • Char 未转换为 int

    由于某种原因 我的 C 程序拒绝将 argv 的元素转换为整数 我不明白为什么 int main int argc char argv fprintf stdout s n argv 1 Make conversions to int in
  • 在 docker 容器内使用 RVM 等版本管理器是一种不好的做法吗?

    我是使用 docker 的新手 到目前为止我无法找到许多包含的 ruby rails 图像RVM or rbenv 我看到的最常见的事情是每个容器有多个tags每个标记的图像版本都有only one安装的 Ruby 版本 看到这个image
  • 我可以从另一个进程中卸载 DLL 吗? (Win32)

    我想从另一个进程卸载 DLL 是否可以 如果是 该怎么做 我使用的是Win32 API 非常感谢 是的 这是可能的 它称为 DLL 弹出 某些 DLL 注入器具有该功能 通常加载 DLL 的方式是通过加载库 http msdn micros
  • 如何:片段内的gridview?

    我想创建一个像 android market 一样的 gridview 我想用互联网上数据库中的图像填充它 它需要与 androidv4 support 一起使用 因为我想运行 2 2 直到 4 0 有人说 在4 0之前不可能创建gridv
  • 如何将 DateTime.TryParse 与 Nullable 一起使用?

    我想使用 DateTime TryParse 方法将字符串的日期时间值获取到 Nullable 中 但是当我尝试这个时 DateTime d bool success DateTime TryParse some date text out
  • CheckedChanged 事件中的问题

    我有一个复选框 并且我已订阅 CheckedChanged 事件 处理程序在那里执行一些操作 我以编程方式选中和取消选中该复选框 例如 chkbx Name Checked true 并且 CheckedChanged 事件被触发 我希望仅
  • 如何创建链式管道?

    我想创建一个简单的链式管道 我发现this https stackoverflow com questions 33658355 piping output from one function to another using python
  • SSIS 脚本组件不允许文本流输出

    我正在尝试使用 SSIS 将 JSON 文件导入到我的数据库中 由于我使用的是 SQL Server 2016 因此我可以将文件放在一行中并使用 OPENJSON 读取它们 我的问题是不想只引入 JSON 文本 我还想需要从文件名和当前目录
  • 如何将CAP文件加载到java卡

    我是java卡的新手 你能帮我看看如何将Applet CAP文件解析为APDU吗 用于将此 CAP 文件安装到支持 GP2 2 的卡上 你应该尝试使用GPShell http sourceforge net projects globalp
  • 无法在 Mac OS X 10.6 上的 Python 中将 Matplotlib 中的字体更改为 Helvetica

    我正在尝试将 matplotlib 字体更改为 helvetica 我想在 PDF 图中使用它 我尝试以下操作 import matplotlib matplotlib use PDF import matplotlib pylab as
  • 将用户重定向到不同 ASP.NET Core Razor 网站中的页面

    我有一个 ASP NET Core 2 1 Razor 应用程序 其中有两个在登录前处于活动状态的菜单项 我想在单击任一菜单项时转移 重定向 到其他网站 我尝试过重定向 如下所示 但当前 url 添加到我指定的字符串中 public IAc
  • 根据水年创建日索引

    我正在处理水文数据 我需要水年 我已经根据之前在此论坛上发布的功能成功创建了一个水年专栏 我想要的是有一个陪伴water day范围从 1 365 闰年为 366 以匹配水年序列 请注意 水年是由其结束的日历年指定的 例如 2010水年从2
  • Linux IPC:共享内存回收

    我有两个进程 生产者和消费者 通过使用生成的共享内存段进行通信 old https stackoverflow com questions 21311080 linux shared memory shmget vs mmap接口而不是 m