读《New Riders - Advanced Linux Programming.chm》笔记4

本文介绍了进程间通信的一种方式——内存共享,并详细探讨了其原理及实现过程。包括内存共享的基本概念、如何通过内核分配和管理共享内存区域、以及如何使用信号量进行同步等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                                                     进程间通信

 1内存共享
  
    1.1 内存共享是最简单最快的通信方法,因为多个进程共同拥有一块内存,避免了系统调用和不必要的数据拷贝,
        由于内核没有对内存共享做同步处理,所以同步我门要自己做,比如,一个内存块在没写入东西之前,不能被读, 两个进程不能同时访问一块内存。我门一般使用semaphores来解决这个问题。
    1.2 内存模式
       
 要使用共享内存,进程必须分配到内存片。要访问内存进程必须连上这个片,完了再释放掉。
 在linux下,每个进程的虚拟内存都是被分成页的。每个进程都维护着一张地址表用来指向自己的内存的(存放真正数据
 的地方)。当多个进程的地址表里都有同一个内存片的地址时,那这块内存片就为共享的内存了。
 当分配一块新的共享内存时,会开辟一个新的虚拟内存页,所以只需一个进程来开辟一个新的共享内存,其他的进程
 要用一块已经存在的内存,只需要在自己的内存表里加上一个到虚拟内存的映射,在使用完后,再释放掉。当没有
 进程要用虚拟内存了,要释放掉虚拟内存。

    1.3 内存分配
       
 进程调用shmget("SHared Memory GET")来分配内存。第一个参数是内存标志,如果使用IPC_PRIVATE则可避免重名;第二个参数getpagesize(),每页的大小,因为
 在linux下内存是以页为单位的。
 第三个参数 IPC_CREAT | IPC_EXCL|S_IRUSR | S_IWUSR(IPC_CREAT,代表建立一个新的内存快,如果以存在描述的块,
 则访问, S_IRUSR,代表共享内存所有者读,S_IWUSR,代表共享内存所有者写,S_IROTH and S_IWOTH 代表
 所有的进程都可写可读;IPC_EXCL,这个标志要跟在 IPC_CREAT后用,如果建立的内存已经存在则出错,有它
 的意思是,一定要建立一个新的内存。
 int  segment_id  =  shmget  (shm_key,  getpagesize  (), IPC_CREAT  |  S_IRUSR  |  S_IWUSER);
 如果调用成功就反回一个标志,如果存在该内存则,检测数据是否已损坏。
例子:
  
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
 
int main ()
{
  int segment_id;
  char* shared_memory;
  struct shmid_ds shmbuffer; //关于共享内存的一些数据
  int segment_size;
  const int shared_segment_size = 0x6400;
 
  /* Allocate a shared memory segment.  */
  segment_id = shmget (IPC_PRIVATE, shared_segment_size,
                     IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
  /* Attach the shared memory segment.  */
  shared_memory = (char*) shmat (segment_id, 0, 0); //连接共享内存,第二个参数为空代表系统会利用一个可用地址来指向共享内存
  printf ("shared memory attached at address %p/n", shared_memory);
  /* Determine the segment's size. */
  shmctl (segment_id, IPC_STAT, &shmbuffer); //得到共享内存的信息
  segment_size  =shmbuffer.shm_segsz;
  printf ("segment size: %d/n", segment_size);
  /* Write a string to the shared memory segment.  */
  sprintf (shared_memory, "Hello, world.");
  /* Detach the shared memory segment.  */
  shmdt (shared_memory);
 
  /* Reattach the shared memory segment, at a different address.  */
  shared_memory = (char*) shmat (segment_id, (void*) 0x5000000, 0); //指定一个地址来连接共享内存
  printf ("shared memory reattached at address %p/n", shared_memory);
  /* Print out the string from shared memory.  */
  printf ("%s/n", shared_memory);
  /* Detach the shared memory segment.  */
  shmdt (shared_memory);
 
  /* Deallocate the shared memory segment.  */
  shmctl (segment_id, IPC_RMID, 0); //removeid干掉共享内存。
 
  return 0;
}
调试::查看正在使用的共享内存
% ipcs -m
 
------ Shared Memory Segments -------
key       shmid     owner     perms     bytes     nattch    status
0x00000000 1627649   user    640       25600     0

----------------------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值