学习笔记-进程间通信(IPC)--消息队列、共享内存、信号量

消息队列、共享内存和信号量有很多相同的地方,所以统称它们为XSI IPC[2]。相同的地方有:(1) 每一个IPC structure(message queue,semaphores,or shared memory segment) in the kenel is referred to by a non-negative integer identifier。identifier是IPC structure的内部名字,对于其他进程来说,是不可见的,所以还要有一个key充当IPC structure的外部名字。Linux下key的数据类型是key_t(定义在 ),是个long integer。(2) 三种IPC都有一些限制,在Linux下使用ipcs -l查看。(3)三种IPC的数据结构的第一个元素是结构类型ipc_perm,它存储有关权限的信息。

共享内存是最快的一种IPC(不只是在XSI IPC中比较)。

1. XSI IPC与pipe、FIFOs比较

XSI IPC are systemwide and do not have a reference count,若没有使用相应的函数删除XSI IPC,创建和使用它们的进程都终止后,XSI IPC还在系统中。Compare this with a pipe, which is completely removed when the last process to reference it terminates. With a FIFO, although  the name stays in the file system until explicitly removed, any data left in a FIFO is removed when the last process reference the FIFO terminates.

XSI IPC are not knowed by names in the file system, 也就不使用file descriptor,所以不能像pipe和FIFO那样,可以使用read、open等FILE I/O。XSI IPC需要增加新的函数,提高了复杂性。

2. 《APUE》书建议:learn pipes and FIFOs, since these two basic technicals can still be used effectively in numerous applications. Avoid using message queues and semaphores in any new applications. Full-duplex pipes and record locking should be considered instead,  as they are far simpler. Shared memory still has its use, although the same functionality  can be provided through the use of the mmap function. The mmap function can be used to map portions of a file into the address space of a process.

3. 消息队列、信号量和共享内存的数据结构和函数很相似,所以下面只列出共享内存的数据结构和函数

内核为共享内存维护的数据结构至少有如下元素(具体的操作系统实现会增加一些元素):

struct shmid_ds {
    struct ipc_perm   shm_perm;
    size_t    shm_segsz; //size of segment in bytes 
    pid_t     shm_lpid;//pid of last shmop()
    pid_t     shm_cpid; //pid of create
    shmatt_t  shm_nattch;//number of current attaches
    time_t    shm_atime; //last-attach time
    time_t    shm_dtime; //last-detach time
    time_t    shm_ctime; //last-change time
};
提供的函数有:
#include 
  
  

   
   //obtain a shared memory identifier

   
   int shmget(key_t key, size_t size, 
   
   int flag);

   
   //variaous shared memory operations

   
   int shmctl(
   
   int shmid, 
   
   int cmd, 
   
   struct shmid_ds *buf);

   
   //attach shared memory to address space

   
   void *shmat(
   
   int shmid, 
   
   const 
   
   void *addr, 
   
   int flag);

   
   //detach shared memory

   
   int shmdt(
   
   void *addr);
  
  
共享内存attach到进程地址空间的什么地方?实验得出是在栈下堆上,实验代码:
int shmid;
printf("&shmid is %lx/n", &shmid);
char* ptr =(char*)malloc(MALLOC_SIZE);
printf("malloced from %lx to %lx/n", (unsigned long)ptr,
          (unsigned long)ptr + MALLOC_SIZE);
shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE);
shmptr = shmat(shmid, 0, 0);
printf("shared memory attached from %lx to %lx/n", (unsigned long)
                 shmptr,  (unsigned long)shmptr + SHM_SIZE); 
shmctl(shmid, IPC_RMID, 0);
注:Intel-based的Linux系统。

参考资料
[1] 《UNIX网络编程第二卷:进程间通信》
[2] 《APUE》
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值