学习了一下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块内存的地址,是否可行?如果共享内存地址在各个进程中处于不同的地址空间段上,那么该怎么告诉服务器客户端在哪个位置写入了数据呢?
(如果直接传地址不行的话,我想的是通过偏移地址来实现,虽然同一段共享内存在不同的进程上的虚拟起始地址不同,但是实际访问的起始地址相同,知道了偏移量,各个进程按照首地址+偏移量就能定位实际写入内存的位置,但是有没有更自然一点的方法呢)
请前辈们指点一二,非常感谢

解决方案 »

  1.   

    @LubinLew 
    谢谢回答
    设置标志这个方法可以,感觉再配合异步事件通知来实现的话应该不错
      

  2.   

    共享内存就是一种进程间通讯的方式,不要用socket去通知了,这样你就忽略了共享内存的这个本质;
    至于你在共享内存的某个偏移处做了更改,服务器其实可以开个线程专门用来更新共享内存的内容到自己的进程空间;
    如果你对实时性有要求的话,可以通过进程锁等来做改进。
      

  3.   

    同步也没必要使用socket 了,把信号量定义在共享内存就行了,可以看看 《UNIX网络编程 卷2:进程间通信》 使用 key 的共享内存是 system V 的共享内存,还有 POSIX 的 共享内存
      

  4.   

    首先需要理解,每个进程都有各自独立的虚拟存储空间,因此在A程序看的addr和B程序看到的addr,即使addr相同,也不一定会在物理存储空间重合。 共享存储说白了就是os为多个程序构造指向相同物理地址的页表项,也就是每个程序都具有影射到该物理地址的页表项。  访问的时候,注意使用相对地址或者直接将一个结构指针指向共享存储,只要大家的结构定义是一样的,那么大家都可以使用各自的结构指针来访问,同时不会出现数据错乱。