共享内存

来源:互联网 发布:希拉里 放过, 知乎 编辑:程序博客网 时间:2024/05/22 02:02
共享内存:     

#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;         /* 分配一个共享内存块 */  
  segment_id = shmget(IPC_PRIVATE, shared_segment_size, 
  IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR ); /* 绑定到共享内存块 */    

 shared_memory = (char*)shmat(segment_id, 0, 0);  

  printf("shared memory attached at address %p\n", shared_memory); /* 确定共享内存的大小 */  
  shmctl(segment_id, IPC_STAT, &shmbuffer);    

 segment_size = shmbuffer.shm_segsz;  
  printf("segment size: %d\n", segment_size);  
  sprintf(shared_memory, "Hello, world."); /* 在共享内存中写入一个字符串 */  
  shmdt(shared_memory); /* 脱离该共享内存块 */  
  shared_memory = (char*)shmat(segment_id, (void*) 0x500000, 0);/* 重新绑定该内存块 */  
  printf("shared memory reattached at address %p\n", shared_memory);  
  printf("%s\n", shared_memory); /* 输出共享内存中的字符串 */    

  shmdt(shared_memory); /* 脱离该共享内存块 */  
  shmctl(segment_id, IPC_RMID, 0);/* 释放这个共享内存块 */    

  return 0;  
}


特点:

1)共享内存是进程间共享数据的一种最快的方法。

 一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。

2)使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥。

若一个进程正在向共享内存区写数据,则在它做完这一步操作前,别的进程不应当去读、写这些数据。

进程间通信总结:

1.消息队列

      消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级,本质就是内核地址空间中的内部链表。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的。

2.共享内存

共享内存指在多处理器的计算机系统中,可以被不同中央处理器访问的大容量内存。由于多个CPU需要快速访问存储器,这样

就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否

则不同的处理器可能用到不同的数据。共享内存是Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,

实际上多个程序间也可以通过共享内存来传递信息。 
共享内存与其他的进程间通信最大的优点是:数据的复制只有两次,一次是从输入文件到共享内存区,一次从共享内存区到输出文

件 

而其他的则是需要复制4次:服务器将输入文件读入自己的进程空间,再从自己的进程空间写入管道/消息队列等;客户进程从

管道消息队列中读出数据到自己的进程空间,最后输出到客户指定的文件中。

3.管道

管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道; 
只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);

单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统

 ,而是自立门户,单独构成一种文件系统,并且只存在与内存中。 

数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且

每次都是从缓冲区的头部读出数据。

4.信号量

信号量又称为信号灯, 信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制。相当于内存中的

标志,进程可以根据它判定是否能够访问某些共享资源,同时,进程也可以修改该标志。除了用于访问控制外,还可用于进程同步

。信号灯有以下两种类型:

二值信号灯:最简单的信号灯形式,信号灯的值只能取0或1,类似于互斥锁。  注:二值信号灯能够实现互斥锁的功能,但两

者的关注内容不同。信号灯强调共享资源, 只要共享资源可用,其他进程同样可以修改信号灯的值;互斥锁更强调进程,占用资

源 的进程使用完资源后,必须由进程本身来解锁

计算信号灯:信号灯的值可以取任意非负值(当然受内核本身的约束)。