当前位置:网站首页>进程间通信
进程间通信
2022-07-31 03:21:00 【大百求知路】
1.管道
概念:管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
创建:创建一个简单的管道,可以使用系统调用pipe()。它接受一个参数,也就是一个包括两个整数的数组。如果系统调用成功,此数组将包括管道使用的两个文件描述符。创建一个管道之后,一般情况下进程将产生一个新的进程
系统调用:pipe();
原型:int pipe(int fd[2]);
返回值:如果系统调用成功,返回0。如果系统调用失败返回-1
errno = EMFILE(没有空闲的文件描述符)
ENFILE(系统文件表已满)
EFAULT(fd数组无效)
特点:管道是单向的,先进先出的,无结构的,固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起。
写进程在管道的尾端写入数据,读进程在管道的首端读出数据。数据读出后将从管道中移走,其他读进程都不能再读到这些数据。
管道提供了简单的流控制机制。进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。同样,管道已写满时,进程再试图写管道,在其他进程从管道中移走数据之前,写进程将一直阻塞。
2.命名管道
命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
命名管道的创建:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname,mode_t mode);
返回值:若成功则为0,若出错则为-1
|所需头文件| #include <sys/types.h>,#include <sys/stat.h> |
|-函数原型-|-int mkfifo(const *pathname,mode_t mode)-|
| 函数传入值 |filename:要创建的管道,mode: O_RDONLY:读管道;O_WRONLY:写管道;O_RDWR:读写管道;O_NONBLOCK:非阻塞
O_CREAT:如果该文件不存在,那么久创建一个洗的文件,并用第三的参数为其设置权限;O_EXCL:如果使用O_CREAT时文件存在,那么可返回错误消息。这一参数可测试文件是否存在。|
FIFO相关出错信息:
EACCES (无存取权限)
EEXIST (指定文件不存在)
ENAMETOOLONG (路径名太长)
ENOENT (包含的目录不存在)
ENOSPC (文件系统剩余空间不足)
ENOTDIR (文件路径无效)
EROFS (指定的文件存在于只读文件系统中)
一旦已经用mkfifo创建了一个FIFO,就可以用open打开它。确实,一般的文件i/o函数(close,read,write,unlink等)都可以用于FIFO。
当打开一个FIFO时,非阻塞标志(O_NONBLOCK)产生下列影响:
(1):在一般情况下(没有说明O_NONBLOCK),只读打开要阻塞到某个其他进程为写打开此FIFO。类似,为写而打开一个FIFO要阻塞到某个其他进程为 读而打开它。
(2):如果指定了O_NONBLOCK,则只读打开立即返回。但是,如果没有进程已经为读而打开一个FIFO,那么只写打开将出错返回,其errno是ENXIO。
类似于管道,若写一个尚无进程为读而打开的FIFO,则产生信号SIGPIPE。若某个FIFO的最后一个写进程关闭了该FIFO,则将为该FIFO的读进程产生一个文件结束标志。
3.信号
信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持unix早期信号语义函数signal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
很多条件可以产生一个信号:
1.当用户按某些终端按键时,产生信号。在终端上按delete键通常产生中断信号;
2.硬件异常产生信号:除数为0,无效的存储访问等等。
3.进程用kill(2)函数可将信号发送给另一个进程或进程组。
4.用户可用kill(1)命令将信号发送给其他进程。
5.当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号。例如SIGPIPE(在管道的读进程已终止后一个进程写此管道)
信号源
内核为进程生产信号,来响应不同的事件,这些事件就是信号源。主要的信号源如下:
1.异常:进程运行过程中出现异常;
2.其他进程:一个进程可以向另一个或一组进程发送信号。
3.终端中断:ctr+c,ctr+\等;
4.作业控制:前台,后台进程的管理;
5.分配额:CPU超过或文件大小突破限制;
6.通知:通知进程某事件发生,如I/O就绪等;
7.报警:计时器到期。
LInux中的信号
kill -l命令显示系统信号
1~31为不可靠信号,34-64为可靠信号
可靠信号支持多次注册,排队处理
下面是几个常见的信号。
SIGINT:按下CTRL+C发出信号,默认操作是中断该进程
SIGQUIT:按下CTRL+\发出信号,默认操作是退出QUIT该进程
SIGTSTP:按下CTRL+Z发出信号,默认操作是暂停该进程
SIGCONT:用于通知暂停的进程继续。
信号出现时按照下列三种方式的一种进行操作。
1.忽略此信号 SIGKILL和SIGSTOP不能被忽略
2.捕捉信号 调用一个用户函数。
3.执行系统默认动作
每一个信号都有一个缺省动作,它是当进程没有给这个信号指定处理程序时,内核对信号的处理。有5种缺省动作
1.异常终止(abort):在进程的当前目录下,把进程的地址空间内容,寄存器内容保存到一个叫做core的文件中,而后终止进程
2.退出(exit):不产生core文件,直接终止进程
3.忽略(ignore):忽略该信号
4.停止(stop):挂起该进程
5.继续(continue):如果进程被挂起,则恢复进程的运行。否则,忽略信号。
4.消息队列:
消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等。它允许一个或多个进程向它写消息,一个或多个进程从中读消息。具有一定的FIFO特性,但是可实现消息的随即查询。这些消息存在于内核中,由“队列ID”来标识。
消息队列的实现包括创建和打开队列,添加消息,读取消息和控制消息队列这四种操作。
msgget:创建和打开队列,其消息数量受系统限制。
所需头文件:include<sys/types.h>;#include<sys/ipc.h>;#include<sys/shm.h>
函数原型:int msgget(key_t key,int flag)
函数传入值:key:返回新的或已有队列的队列ID,IPC_PRIVATE;Flag:和共享内存的这个参数是一样的,也是权限标识。
函数返回值:成功:消息队列ID;出错:-1
msgsnd:添加消息,将消息添加到消息队列尾部。
所需头文件:include<sys/types.h>;#include<sys/ipc.h>;#include<sys/shm.h>
函数原型:int msgsnd(int msqid,const void *prt,size_t size,int flag)
函数传入值:msqid:消息队列的队列ID;prt:指向消息结构的指针。该消息结构msgbuf为:struct msgbuf{long mtype;//消息类型char mtext[1];//消息正文};size:消息的字节数,不要以null结尾;flag:IPC_NOWAIT若消息并没有立即发送而调用进程会立即返回;0:msgsnd调用阻塞直到条件满足为止
函数返回值:成功:0;出错:-1
msgrcv:读取消息,从消息队列中取走消息。
所需头文件:include<sys/types.h>;#include<sys/ipc.h>;#include<sys/shm.h>
函数原型:int msgrcv(int msgid,struct msgbuf*msgp,int size,long msgtype,int flag)
函数传入值:msqid:消息队列的ID;msgp:消息缓冲区;size:消息的字节数,不要以null结尾。Msgtype:0:接收消息队列中第一个消息;大于0:接收消息队列中第一个类型为msgtyp的消息;小于0:接收消息队列中第一个类型值不小于msgtyp绝对值且类型值又最小的消息;flag:MSG_NOERROR:若返回的消息比size字节多,则消息就会截短到size字节,且不通知消息发送进程;IPC_NOWAIT若消息并没有立即发送而调用进程会立即返回;0:msgsnd调用阻塞直到条件满足为止
函数返回值:成功:0;出错:-1;
msgctl:控制消息队列。
所需头文件:include<sys/types.h>;#include<sys/ipc.h>;#include<sys/shm.h>
函数原型:int msgctl(int msgqid,int cmd,struct msqid_ds *buf)
函数传入值:msqid:消息队列的队列ID;cmd:IPC_STAT:读取消息队列的数据结构msqid_ds,并将其存储在buf指定的地址中;IPC_SET:设置消息队列的数据结构msqid_ds中的ipc_perm元素的值。这个值取自buf参数;IPC_RMID:从系统内核中移走消息队列;buf:消息队列缓冲区
函数返回值:成功:0;失败:-1;
5.共享内存
使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其他通信机制,如信号量结合使用,来达到进程间的同步及互斥。
ipcs指令是查看系统中共享内存数和信号量数组和消息队列数的指令。
system(ipcs -m)是系统显示共享内存区域。
shmget()创建共享内存
所需头文件:include<sys/types.h>;#include<sys/ipc.h>;#include<sys/shm.h>
函数原型:int shmget(key_t key,int size,int shmflg)
函数传入值:Key:IPC_PRIVATE;Size:共享内存区大小;Shmflg:同open函数的权限为,也可以用八进制表示法
函数返回值:成功:共享内存段标识符;出错:-1
shmat()函数映射共享内存
所需头文件:include<sys/types.h>;#include<sys/ipc.h>;#include<sys/shm.h>
函数原型:char*shmat(int shmid,const void*shmaddr,int shmflg)
函数传入值:shmid:要映射的共享内存区标识符;shmaddr:将共享内存映射到指定位置(若为0,则表示把该段共享内存映射到调用进程的地址空间);shmflg:SHM_RDONLY:共享内存只读,默认0:共享内存可读写。
函数返回值:成功:被映射的段地址;失败:-1
shmdt()分离共享内存(虚拟地址和物理地址进行分离)
所需头文件:include<sys/types.h>;#include<sys/ipc.h>;#include<sys/shm.h>
函数原型:int shmdt(const void*shmaddr)
函数传入值:Shmaddr:被映射的共享内存段地址
函数返回值:成功:0;出错:-1
边栏推荐
- A brief introduction to the showDatePicker method of the basic components of Flutter
- The distance value between two arrays of LeetCode simple questions
- 【编译原理】递归下降语法分析设计原理与实现
- 【HCIP】ISIS
- 【Cocos Creator 3.5】缓动系统停止所有动画
- With 7 years of experience, how can functional test engineers improve their abilities step by step?
- CloudCompare & PCL calculate the degree of overlap between two point clouds
- [Compilation principle] Lexical analysis program design principle and implementation
- MP使用时的几个常见报错
- 【AUTOSAR-RTE】-5-Explicit(显式)和Implicit(隐式) Sender-Receiver communication
猜你喜欢
【编译原理】词法分析程序设计原理与实现
Problems that need to be solved in distributed system architecture
MP使用时的几个常见报错
Ambiguous method call.both
MultipartFile file upload
7年经验,功能测试工程师该如何一步步提升自己的能力呢?
Detailed explanation of TCP (1)
TCP详解(二)
VS QT - ui does not display newly added members (controls) || code is silent
LeetCode每日一练 —— OR36 链表的回文结构
随机推荐
Redis实现分布式锁
beforeDestroy与destroyed的使用
Ambiguous method call.both
Mysql 45 study notes (twenty-five) MYSQL guarantees high availability
addressable in Golang
【编译原理】词法分析程序设计原理与实现
Database implements distributed locks
return in try-catch
[C language] General method of expression evaluation
MP使用时的几个常见报错
Local area network computer hardware information collection tool
Automation strategies for legacy systems
Map.Entry理解和应用
Mysql 45讲学习笔记(二十五)MYSQL保证高可用
浅识Flutter 基本组件之CheckBox组件
选好冒烟测试用例,为进入QA的制品包把好第一道关
【编译原理】递归下降语法分析设计原理与实现
LeetCode每日一练 —— 138. 复制带随机指针的链表
CloudCompare&PCL 计算两个点云之间的重叠度
The Map Entry understanding and application