linux如何查看共享内存,linux下的进程间通信-管道及共享内存

 2023-09-25 阅读 27 评论 0

摘要:进程间通信(IPC):操作系统为用户提供的集中进程间通信方式; 为什么要进程间通信? linux如何查看共享内存、进程之间具有独立性(每个进程有自己的虚拟地址空间),访问自己的虚拟地址,无法访问同一块区域,

进程间通信(IPC):操作系统为用户提供的集中进程间通信方式;

为什么要进程间通信?

linux如何查看共享内存、进程之间具有独立性(每个进程有自己的虚拟地址空间),访问自己的虚拟地址,无法访问同一块区域,因此无法实现数据通信。

针对不同的通信场景提供多种通信方式:数据传输-管道/消息队列数据共享-共享内存进程控制-信号量。

管道:本质:内核中的一块缓冲区;多个进程若访问同一个管道(一块缓冲区)可实现通信;

进程间通信共享内存,种类:匿名管道/命名管道

匿名管道:内核中的缓冲区没有具体的标识符;只能用于亲缘关系的进程间通信;

       原因:只能通过子进程复制父进程的方式获取管道的操作句柄;父进程创建管道的时候操作系统会返回管道的操作句柄(文件描述符)。

docker 容器间通信,如何创建匿名管道?

int pipe(int pipefd[2]);pipefd[2]--具有两个int型节点的数组的首地址,用于接收创建管道返回的操作句柄。

pipefd[0]-用于管道中读取数据;pipefd[1]-用于向管道中写入数据。

管道是一个单向的资源传输,自身并不确定资源的传输方向;管道是一个半双工通信(可选择方向的单向传输

返回值:成功返回0,失败返回错误代码。

子进程打印的信息,打印到了shell提示信息的后边:父进程先于子进程退出,子进程成为孤儿进程运行在后台。子进程后台运行时,shell切换回到前台打印提示信息,然后子进程打印信息就会打印到提示信息后边。

父进程创建了子进程,谁先运行不一定,取决于cpu的调度。

管道的读写特性:

1.若管道中没有数据,则调用read读取数据会阻塞,进程暂停执行。

2.若管道中数据满了,则调用write写入数据会阻塞;管道是一块缓冲区(内存空间),并非无限制大

阻塞:为了完成一个功能,发起调用,若当前不具备完成条件,则一直等待。

如下:

结果如下:管道是一块缓冲区,并非无限制大。

3.若管道的所有读端pipefd[0]被关闭,则继续调用write会产生异常导致进程退出

关闭所有读端,会发生程序发生异常,直接退出。

4.若管道的所有写端pipefd[1]被关闭,则继续调用read,读完管道中的数据后不再阻塞,而是返回0.

关闭所有写端,程序读取不到数据。

我们写的程序大多都是守护进程,是一种特殊的孤儿进程,孤儿进程不危险,危险的是僵尸进程。

通过匿名管道实现命令行中管道符的作用:ps -ef |grep ssh

ps -ef:默认讲结果打印到标准输出             grep ssh:默认从标准输入读取数据进行过滤

ps进程如何将输出结果,并不写入标准输出而是写入到管道中呢??将标准输出重定向管入道写端

grep进程如何做到不从标准输入读取数据,而是从管道读取数据呢??将标准输入重定向管道写入端。

grep过滤了结果后并不会退出,循环读取数据进行过滤,因此ps进程退出后需要关闭所有写端,没有数据可写了。

结果如下:

命名管道:内核中的缓冲区,具有标识符,标识符是一个可见于文件系统的管道文件,能够被其他进程找到并打开管道文件则可以获取管道的操作句柄。---可用于同一主机上的任意进程间通信

打开2个端口,可以进行2个端口间的进程间通信,一方打印出来,另一方退出。

多个进程通过命名管道通信是通过打开命名管道文件访问同一块内核中的缓冲区实现通信

可通过:mkfifo 创建管道文件

代码中的操作:int mkfifo(char *filename,mode_t mode);

filename:管道文件名称; mode;管道文件权限;成功返回0;失败返回-1

剩下的操作与文件IO操作雷同

open打开命名管道特性:若文件以只读打开,则会阻塞,直到文件被以写的方式打开

                                        若文件以只写打开,则会阻塞,直到文件被以读的方式打开

vnew  ./fifo_write.c同时打开这个进程,gg-y-G-P把一个vi程序全文复制粘贴到另一个ci中。

 

 总结:管道本质:内核中一块缓冲区

            分类:匿名管道-具有亲缘关系的进程间通信

                    命名管道-用于同一主机上的任意进程间通信

特性:1.管道是半双工通信(可选择方向的单向传输)

           2.管道读写特性(匿名和命名管道一样)

                      若管道中没有数据则read阻塞;若管道中数据满了则write阻塞;

                      若管道所有读端关闭则write会触发异常;若管道所有写端关闭则read读完数据返回0,不再阻塞。

           3.管道生命周期随进程(打开管道的所有进程退出,管道就会被释放(命名管道一样,本质都是缓冲区,文件只是标识符))

           4.管道提供字节流传输服务(可靠的,有序的,基于连接的一种灵活性比较高的传输)

           5.    命名管道额外有一个打开特性:

                                        若文件以只读打开,则会阻塞,直到文件被以写的方式打开

                                        若文件以只写打开,则会阻塞,直到文件被以读的方式打开

           6.管道自带同步与互斥

                                       同步:通过条件判断实现临界资源操作的合理

                                       互斥:通过唯一访问实现临界资源操作的安全

共享内存:

特性:共享内存是最快的进程间通信方式

本质原理:在物理内存上开辟一块空间,多个进程可以将同一块物理内存空间映射到自己的虚拟地址空间,通过自己的虚拟地址直接访问这块空间,通过这种方式实现数据共享

管道通信中:涉及到两次用户态和内核态之间的数据拷贝;将数据写入管道,从管道读取数据

共享内存的通信直接通过虚拟地址访问物理内存实现共享内存中的数据操作,速度最快。

共享内存的生命周跟随内核,在物理内存开辟空间,信息存储在内核;共享内存是属于内核的一个进程间通信资源;不会随着进程的退出而释放;内核重启会释放或者手动释放,否则一直存在于内核。

共享内存的操作流程:

              1.创建共享内存--在物理内存上开辟空间

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

key:内核中共享内存的标识符--多个进程通过相同的标识符才能打开同一个共享内存

size:共享内存大小--以内存页为单位进行分配

shmflg:IPC_CREAT-存在则打开,不存在则创建|IPC_EXCL-与IPC_CREAT同时使用,若存在则报错,不存在则创建|mode

返回值:返回一个非负整数--共享内存的操作句柄,失败返回-1.

生成一个key值,key_t ftok(const char *pathname,int proj_id);--通过inode节点号与projid合成一个key。

              2.进程将共享内存映射为到自己虚拟地址空间

void *shmat(int shmid, const void *shmaddr, int shmflg);

shmid:shmget返回的共享内存操作句柄

shmaddr:共享内存映射在虚拟地址空间中的首地址--通常置NULL

shmflg:映射成功之后对共享内存可进行的操作, SHM_RDONLY用于只读(前提是有读的权限)/0-默认可读可写

返回值:返回共享内存映射在虚拟地址空间中的首地址--通过这个首地址进行后续的内存操作。失败返回-1(void*)-1

              3.基本的内存操作都可以对这块空间进行操作

int shmdt(const void *shmaddr);

shmaddr:映射在虚拟地址空间中的首地址,成功返回0,失败返回-1

              4.解除虚拟地址空间与共享内存的映射关系

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

shmid:共享内存操作句柄

cmd:对共享内存想要进行的操作 IPC_RMID-删除共享内存

buf:用于获取/设置共享内存信息的结构,不适用则置NULL

成功返回0;失败返回-1;

5.释放共享内存资源

进程间通信资源的命令操作:

操作命令:ipcs 查看所有的进程间通信资源 

ipcs -m 查看共享内存进程间通信

ipcs -q 查看消息队列进程间通信

ipcs -s 查看信号量进程间通信

ipcrm -m id:删除进程间通信资源

 共享内存删除的时候,并不会立即被删除,只是将其状态置为被销毁状态,移除标识,--为了不让这个共享内存继续被其他进程映射连接,然后等到当前共享内存映射连接数为0的时候,才会真正删除这块共享内存。

      

 共享内存数据的写入,是一种针对地址指向空间的覆盖式写入。

共享内存:本质原理:多个进程将同一块物理内存映射到自己的虚拟地址空间实现数据共享

特性:

1.最快的进程间通信方式

2.生命周期随内核

注意:共享内存并没有自带同步与互斥--多个进程进行访问的时候存在安全问题

操作:代码操作流程/具体接口+命令操作ipcs/ipcrm

管道pipefd是传输数据,共享内存主要用于数据共享

管道生命周期随进程,共享内存生命周期随内核

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/94852.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息