Linux进程间通信-2

在上一篇博客中,我们提到的进程间通信的四种方式:管道,共享内存,消息队列和信号量,并对管道的内容进行了讲解。本篇博客我们承接上文,接下来的进程间通信内容。

目录

1.共享内存

1.1内容

1.2操作

1.2.1shmget接口

1.2.2shmat接口

1.2.3shmdt接口

1.2.4shmctl接口

1.2.5应用

1.共享内存

1.1内容

共享内存用于多个进程之间的数据共享,是所有进程间通信方式中最快的通信方式。

共享内存的原理也十分简单:开辟一块物理内存,然后多个进程将这一块物理内存都映射到自己的页表之中,通过自己的虚拟地址来访问这块共享内存物理地址中的数据。

对于共享内存而言,进程可以直接对其进行访问。较于管道进程需要将数据拷贝到其中(写入),再由其他进程将数据读取拷贝到自己的内存(读取),少了两次拷贝过程,通信时间大大降低。因此,我们说共享内存是最快的进程间通信方式。

1.2操作

1.2.1shmget接口

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

shmget接口的作用便是创建一个共享内存,其中key是共享内存的标识符(名字),size是需要创建的共享内存大小,最好是PAGE_SZIE(4096kb)的整数倍;

shmflg是关键字:IPC_CREAT--如果共享内存不存在则创建,若存在则开;IPC_EXCL--与IPC_CREAT搭配使用,如果共享内存不存在则创建,若存在则报错;mode_flags--共享内存的访问权限0664。

shmget创建成功则返回一个非负整数(操作句柄);失败则返回-1。

1.2.2shmat接口

void* shmat(int shmid, void* addr, int shmflag);

shmat接口的作是将共享内存的地址信息映射到进程中的虚拟地址空间,其中shmid是shmget打开共享内存是时返回到的操作句柄,addr是映射首地址,不过我们一般将其制NULL,让操作系统进行分配,防止人为错误;shmflag:默认为0表示可读可写,SHM_RDONLY表示只读(前提是权限允许)。

shmat映射成功则返回映射的首地址,失败返回(void*)-1。当我们获取到首地址之后,就可以对共享内存中的内容进行操作。

1.2.3shmdt接口

int shmdt(const void* shmaddr);

shmdt接口是解除共享内存和进程之间的映射关系,其中shmaddr是映射首地址,也就是shmat接口的返回值。

shmat接触映射关系成功则返回0;失败则返回-1。

1.2.4shmctl接口

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

shmctl接口是实现对共享内存的控制,一般用于标记共享内存的删除。其中shmid是shmget接口返回的操作操作句柄;cmd是对共享内存进行的操作:IPC_RMID--标记一个共享内存段需要进行删除;buf用于设置或者获取共享内存信息,当cmd是IPC_RMID时被忽略。

值得注意的是,其中RMID叫做标记删除,而不是删除。这是因为如果当多个进程访问同一个共享内存时,如果其中某个进程突然要删除该共享内存,直接对其进行删除很明显会导致其他进程访问错我。

所以我们对该共享内存进行标记,被标记的共享内存不再接受新的映射,直到当前映射连接计数为0时,在对该共享内存进行实际删除。也就是说接口只是进行删除标记,而实际上的上述由操作系统来完成。

1.2.5应用

照例来书写程序来对上述接口的使用和功能进行实践和展示。

先完成向共享内存写入数据:

然后进行向共享内容读取数据:

最后复制终端,一个终端进行向共享内存写入数据,一个终端进行向共享内存读取数据,得到结果如下:

 如此结果很好的展现了共享内存对进程间通信的实现。

猜你喜欢

转载自blog.csdn.net/m0_56821563/article/details/129984312
今日推荐