linux下共享内存怎么在不同的进程之间传送地址

libraacrab 2017-08-15 10:27:40
学习了一下unix/linux下高级进程间通信的内容,关于共享内存的部分非常感兴趣
经过了解,共享内存可以被不同的进程通过相同的key值获取到并挂载到各自的虚拟进程空间地址上,然后根据shmat返回的地址进行访问,但是一旦挂载到虚拟地址空间上,虽然实际访问的是同一块内存地址,但是每个进程却不能互相通知对方我在哪个地址段上做了修改,比如现在有两个进程,客户端和服务器,客户端用key=1注册了1G共享内存,服务器通过key=1获取到已经注册的1G共享内存,但是在客户端中这1G内存被分割成1024块1M的内存块,假设现在客户端在第10块内存块上填充了1M的内容,想要让服务器知道它在这个地方进行了写入,希望服务器在此进行内容读取。
现在想通过unix socket的方式来传递这个信息,按照函数send(int sockfd, const void* buf,size_t nbytes,int flags)的用法,应该传输的是第10块内存的内容,现在只需要传输第10块内存的地址,是否可行?如果共享内存地址在各个进程中处于不同的地址空间段上,那么该怎么告诉服务器客户端在哪个位置写入了数据呢?
(如果直接传地址不行的话,我想的是通过偏移地址来实现,虽然同一段共享内存在不同的进程上的虚拟起始地址不同,但是实际访问的起始地址相同,知道了偏移量,各个进程按照首地址+偏移量就能定位实际写入内存的位置,但是有没有更自然一点的方法呢)
请前辈们指点一二,非常感谢
...全文
1008 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
mymtom 2017-10-09
  • 打赏
  • 举报
回复
客户机用消息队列通知服务器
chaoswind 2017-09-30
  • 打赏
  • 举报
回复
首先需要理解,每个进程都有各自独立的虚拟存储空间,因此在A程序看的addr和B程序看到的addr,即使addr相同,也不一定会在物理存储空间重合。 共享存储说白了就是os为多个程序构造指向相同物理地址的页表项,也就是每个程序都具有影射到该物理地址的页表项。 访问的时候,注意使用相对地址或者直接将一个结构指针指向共享存储,只要大家的结构定义是一样的,那么大家都可以使用各自的结构指针来访问,同时不会出现数据错乱。
zhxianbin 2017-09-28
  • 打赏
  • 举报
回复
同步也没必要使用socket 了,把信号量定义在共享内存就行了,可以看看 《UNIX网络编程 卷2:进程间通信》 使用 key 的共享内存是 system V 的共享内存,还有 POSIX 的 共享内存
zhxianbin 2017-09-28
  • 打赏
  • 举报
回复
但是每个进程却不能互相通知对方我在哪个地址段上做了修改, 这个说法不对,你可以在共享内存区定义一个结构体来记录这些
aTimer 2017-09-28
  • 打赏
  • 举报
回复
共享内存就是一种进程间通讯的方式,不要用socket去通知了,这样你就忽略了共享内存的这个本质; 至于你在共享内存的某个偏移处做了更改,服务器其实可以开个线程专门用来更新共享内存的内容到自己的进程空间; 如果你对实时性有要求的话,可以通过进程锁等来做改进。
jamon_tan 2017-09-12
  • 打赏
  • 举报
回复
不同的进程传地址也用不了
LubinLew 2017-08-16
  • 打赏
  • 举报
回复
通常共享内存的读写是通过信号量同步的,如果修改的数据是原子性的,可以直接修改,不需要同步. 可以在共享内存的开头设置标志, 表示哪些数据修改了
libraacrab 2017-08-16
  • 打赏
  • 举报
回复
@LubinLew 谢谢回答 设置标志这个方法可以,感觉再配合异步事件通知来实现的话应该不错

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧