位置: 编程技术 - 正文

linux使用共享内存通信的进程同步退出问题(linux的shm共享内存)

编辑:rootadmin

推荐整理分享linux使用共享内存通信的进程同步退出问题(linux的shm共享内存),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:linux系统共享文件命令,linux共享文件,linux共享内存是什么意思,linux如何使用共享文件夹,linux共享内存是什么意思,linux如何使用共享文件夹,linux的共享内存如何实现,linux共享文件,内容如对您有帮助,希望把文章链接给更多的朋友!

两个甚至多个进程使用共享内存(shm)通信,总遇到同步问题。这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了。这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了。举个例子:进程负责读写数据库A,进程B负责处理数据。那么进程A得比进程B晚退出才行,因为要保存进程B处理完的数据。可是A不知道B什么时候退出啊。A、B是无关联的进程,也不知道对方的pid。它们唯一的关联就是读写同一块共享内存。正常情况下,进程B在共享内存中写个标识:进程A你可以退出了,也是可以的。不过进程B可能是异常退出,连标识都来不及写。其次,共享内存用来做数据通信的,加这么个标识感觉不太好,有滥用的感觉。

  采用socket通信没有这个问题,因为进程B退出怎么也会导致socket断开,哪怕是超时。但shm却没有协议来检测这些行为,如果自己也做一个未免太麻烦。那就从共享内存下手吧。

  共享内存是由内核来管理的,一个进程删除本身打开的共享内存并不影响另一个进程的共享内存,哪怕都是同一块共享内存。这是因为共享内存在内核中一个引用计数,一个进程使用该共享内存就会导致引用计数加1。如果其中一个进程调用了删除函数,只有这个计数为0才会真正删除共享内存。那么,需要最后才退出的进程检测这个计数就可以了。

  在System V的共享内存中,创建一个共享内存会初始化一个结构:

复制代码代码如下:struct shmid_ds { struct ipc_perm shm_perm; /* Ownership and permissions */ size_t shm_segsz; /* Size of segment (bytes) */ time_t shm_atime; /* Last attach time */ time_t shm_dtime; /* Last detach time */ time_t shm_ctime; /* Last change time */ pid_t shm_cpid; /* PID of creator */ pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */ shmatt_t shm_nattch; /* No. of current attaches */ ... };

使用shmctl函数可以读取该结构体,其中的shm_nattch就是使用该共享内存的进程数。

  不过,现在有了新的POSIX标准,当然要用新标准了。shm_open创建的共享内存也具有“一个进程删除本身打开的共享内存并不影响另一个进程的共享内存”的特点。可是用shm_open创建的共享内存不再有上面的结构,那么,内核是怎么管理shm_open创建共享内存??看下面的源码:

linux使用共享内存通信的进程同步退出问题(linux的shm共享内存)

复制代码代码如下:/* shm_open - open a shared memory file */</p><p>/* Copyright , Red Hat Inc. */</p><p>#include <sys/types.h>#include <sys/mman.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <limits.h></p><p>intshm_open (const char *name, int oflag, mode_t mode){ int fd; char shm_name[PATH_MAX+] = "/dev/shm/";</p><p> /* skip opening slash */ if (*name == '/') ++name;</p><p> /* create special shared memory file name and leave enough space to cause a path/name error if name is too long */ strlcpy (shm_name + 9, name, PATH_MAX + );</p><p> fd = open (shm_name, oflag, mode);</p><p> if (fd != -1) { /* once open we must add FD_CLOEXEC flag to file descriptor */ int flags = fcntl (fd, F_GETFD, 0);</p><p> if (flags >= 0) { flags |= FD_CLOEXEC; flags = fcntl (fd, F_SETFD, flags); }</p><p> /* on failure, just close file and give up */ if (flags == -1) { close (fd); fd = -1; } }</p><p> return fd;}

我嚓,这就是创建一个普通的文件啊,只是创建的位置在/dev/shm下(也就是RAM上)。再来看看删除共享内存的函数shm_unlink:

复制代码代码如下:/* shm_unlink - remove a shared memory file */</p><p>/* Copyright , Red Hat Inc. */</p><p>#include <sys/types.h>#include <sys/mman.h>#include <unistd.h>#include <string.h>#include <limits.h></p><p>intshm_unlink (const char *name){ int rc; char shm_name[PATH_MAX+] = "/dev/shm/";</p><p> /* skip opening slash */ if (*name == '/') ++name;</p><p> /* create special shared memory file name and leave enough space to cause a path/name error if name is too long */ strlcpy (shm_name + 9, name, PATH_MAX + );</p><p> rc = unlink (shm_name);</p><p> return rc;}

这也只是一个普通的unlink函数。也就是说,POSIX标准的共享内存就是一个文件。所谓的“一个进程删除本身打开的共享内存并不影响另一个进程的共享内存”就相当于你用fstream对象打开了一个文件,然后去文件夹把文件删除了(也就是对文件进行了unlink操作),可是fstream对象还可以正常读写文件,并没有什么引用计数。这下好了,进程退出时又没法同步了。

  不过,在linux下怎么会有解决不了的问题呢?解决不了只能说明自己太菜。既然是文件,那就从文件下手。那文件有什么是原子操作,又可以计数的呢。答案:硬链接。比如:

复制代码代码如下:xzc@xzc-HP-ProBook-s:/dev/shm$ stat abc 文件:"abc" 大小:4 块:8 IO 块: 普通文件设备:h/d Inode: 硬链接:1权限:(/-rw-rw-r--) Uid:( / xzc) Gid:( / xzc)最近访问:-- ::. +最近更改:-- ::. +最近改动:-- ::. +创建时间:-xzc@xzc-HP-ProBook-s:/dev/shm$

这个硬链接可以通过fstat函数获取。可是要这样实现的话,意味着需要先创建一块共享内存,每个进程引用的时候需要调用link函数来创建一个硬链接。问题解决了,可是这样会在/dev/shm下多个N多个文件。这可是RAM啊,虽然现在的服务器都比较牛,但这样做也不太好吧。好吧,还有一个flock文件锁。flock使用LOCK_SH参数多个进程对同一个文件加锁。这样,进程B初始化共享内存时加锁(可以有多个这样的进程),在退出(包括异常退出)时解锁。进程A在退出时检测这个锁。当发现无锁时说明可以安全退出了。

  同步退出的问题基本解决了。来不及写代码去验证,下次吧。

PS:内核unlink时应该也是有计数才知道当前有没有进程打开文件,在什么时候应该删除文件。这个还得去查资料,看用不用得上。另外lsof这个工具是可以检测到所有打开该共享内存的进程及相应的状态。这个应该也是有对应的api的,只是现在还没搞懂。

Linux系统下如何配置安装SSH服务?如何开启SSH服务? SSH作为Linux远程连接重要的方式,如何配置安装linux系统的SSH服务,如何开启SSH?下面来看看吧(本例为centos系统演示如何开启SSH服务)工具/原料linuxcent

Linux下swap耗尽该怎么办?如何释放swap? Linux下交换内存耗尽如何查看及如何处理。以及查看shell脚本描述。交换内存不足时,启动应用时会报内存不足。1、启动应用时报内存不足,直接Linux命

Linux chmod命令及权限含义 对于一条权限赋值命令:sudochmod-R;我们必须了解其含义:(1)各字段含义:sudochmod-R(更改文件夹及其子文件夹)7(所有者权限)6(组用户权限)4

标签: linux的shm共享内存

本文链接地址:https://www.jiuchutong.com/biancheng/368224.html 转载请保留说明!

上一篇:linux下通过ntp时间同步方法(linux ntp查看)

下一篇:Linux系统下如何配置安装SSH服务?如何开启SSH服务?(linux系统怎样)

  • 电子税务局能查到个税申报信息吗
  • 注册资本金入账需要缴税么
  • 期末现金及现金等价物余额公式
  • 小规模纳税人无进项票怎么办
  • 小微企业免税销售额和其他免税销售额
  • 没有以前年度损益调整这个科目,怎么增加?
  • 会计核算原则主要包括
  • 金税盘在电脑上怎么打开
  • 2021申请一般纳税人公司的条件
  • 提供境外服务
  • 股权转让为什么不征收增值税
  • 电子发票怎么作废操作流程视频
  • 零申报的企业所得税年报怎么填
  • 客户扣款会计分录明细科目
  • 广播影视服务需要交文化事业建设费吗
  • 怎么把公司账户的钱转到个人账号
  • 主机 bios
  • 行政事业单位职工体检依据
  • 车辆购置税如何计算器
  • 银行承兑汇票质押贷款骗局
  • igfxext.exe
  • 备用金借款有利息吗
  • 呆账核销的条件有哪些
  • PHP:oci_field_name()的用法_Oracle函数
  • php load
  • 明细账是什么样子
  • 装修费怎么记会计科目
  • ccmexec.exe是什么程序
  • 外商投资工业企业有哪些
  • 土地增值税的计算方法和步骤例题
  • 支付境外佣金交多少税
  • 结转去年成本
  • vue2:elementUI中Form 表单在特定情况下做动态rules添加删除
  • php单例模式的简写是什么
  • vue动态组件component原理
  • vue使用计算属性
  • vue sha256加密
  • win11装双系统虚拟机mac
  • 最新的目标检测算法2020
  • php类和对象的关系
  • 6款好用的ppt制作软件推荐
  • 印花税计税基础含增值税
  • 公务交通通讯补贴
  • 公司给员工租房进项税可以抵扣吗
  • 会计实操和实际工作一样吗
  • 特殊劳动关系和社会关系
  • 税务登记程序有哪些
  • 工会经费通过应交税费科目核算吗
  • 报销差旅费的进项税额
  • 固定资产接受捐赠的条件
  • 固定资产核销是资产损失吗
  • 建筑企业预缴税款怎么算
  • 会计账户与银行账户
  • 传媒公司的骗局把戏
  • 公司车辆做账交增值税吗
  • 股权激励费用摊销意思是
  • 技术服务费发票怎么开
  • 借方是收入还是支出损益类
  • 如何在电子税务局变更办税人员
  • 发票抵扣联要放在凭证里面吗
  • 长期应付职工薪酬属于其他非流动负债吗
  • 账簿设计原则的主要内容
  • mysql5.0安装
  • win8系统停止服务
  • linux指定格式显示日期
  • 飞行体验设备
  • w7系统序列号怎么查
  • cocos2dx性能优化与包体优化
  • Unity3D游戏开发基础
  • javascript运用
  • android开发范例实战宝典
  • python2与python3的区别
  • 遮罩层 css
  • jquery实现二级联动菜单
  • js怎么设置字体
  • python中的字符串常量
  • 非正常户解除申请理由
  • 五证合一后还需要去税务局吗
  • 公司零申报可以交社保吗
  • 云南省国家税务局APP
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设