一、进程通信//通信方式:管道、信号量、共享内存、消息队列、套接字
1、管道:
(1)两个进程之间用来传递数据的
//管道操作的必须是两个进程,一个进程将会阻塞,两个进程必须同时进行匹配操作(例如:一读一写)
如果写的进程结束,读也不会读到数据,但读的进程不会堵塞。
(2)分类:
有名管道: mkfifo f i f o(建立一个有名管道文件)
A.有名管道的属性信息存在磁盘上的,如属主,创建时间,权限等,名字等
B.写入管道的数据,在内存中
C.要打开有名管道,需要俩个进程,一个读一个写
D.写端关闭,读端返回,返回值为0
E..读端关闭,写端写入数据之后程序结束,收到read给出的异常结束信号结束
无名管道:没有名字,直接给出文件读和写的文件描述符(只能运用在父子进程中 (父进程进行写操作,子进程进行读操作))
先创建管道文件后,才能fork(顺序不同会有不同的结果)
(3)无名和有名的区别:
A、有名的名字存在磁盘上,无名没有名字
B、有名可以运用在任意俩个管道之间,而无名管道只能用在父子进程中
(4)在一个代码中直接进行操作
Int f d [2]
Pipe (fd);//fd[0]写fd[1]读
命令管道:
(5)全双工:电话(俩端可以同时进行)
半双工:对讲机(管道属于)(一端进行输出,一端进行输入)
单工:收音机(只能单一的功能)
(6)管道的实现:利用一个头指针进行写操作,尾指针进行读操作,(形成一个循环的单链表)
2、信号量//解决同步进程
(1)同步:是对两个进程的同一资源的访问
(2)临界资源:同一时刻只允许一个进程访问的资源
(3)临界区:访问临界资源的代码段//只允许一个进程存在
(4)信号量:特殊的变量
P、V操作(原子操作)//可以判断资源能否被访问
P :获取资源//值为0阻塞
V :释放资源
3、共享内存:两个进程可以直接共享访问同一块内存区域;
实现共享内存的方法:
(1)创建内存共享区,通过shmget()函数实现//创建、获取
(2)通过shmat()函数将共享内存映射到进程1中,并与某个特定的key值绑定
(3)进程2通过进程1中shmat()函数和同一个key值执行shmat()函数,将共
享内存映射到进程2中
(4)共享内存实现两个映射后,进程之间可以利用该区域进行信息交互
(5)通过shmct()函数实现撤销内存映射关系
(6)通过shctl函数实现删除共享内存
4、消息队列:是内核地址空间中的内部链表,通过linux内核在各个进程之间传递内容,
消息顺序的以不同种方式发送到消息队列中;
(1)每个消息队列都用IPC标识符来标识唯一的 ,每个消息队列中的消息又构
成了一个独立的链表
(2)内核中,每个消息队列都有一个结构体,每个结构体保存着当前状态信息
结构体ipc_perm保存着消息队列的一些重要的信息,比如说消息队列关联的键值,消息队列的用户id组id等。
(3)消息队列的实质是一个链表,通过msgget()函数来创建一个新的队列或者打开一个存在的队列;
(4)通过msgsnd()函数来向队列末端添加消息;
(5)通过msgrcv()函数从队列中取消息
(6)由msqid标识的消息队列执行cmd操作,共有三种cmd操作:IPC_STAT、IPC_SET 、IPC_RMID。
IPC_STAT:该命令用来获取消息队列信息
IPC_SET:该命令用来设置消息队列的属性
IPC_RMID:删除msqid标识的消息队列;
5.套接字:不局限与一台计算机上的资源,除了可以在本地使用,还可以在网络中运用