进程间的四种通信方式
管道是连接读写进程的一种特殊文件,也称为管道文件。管道文件存在于外存,其中的消息没有固定长度,能用于进程间大量的信息通信。向管道提供输入的发送进程以字符流的形式将大量的数据送入管道。接收管道输出的接收进程,从管道中接收数据。管道机制需要提供以下功能:
- 互斥功能:当一个进程正在对管道执行读写操作时,其他进程必须等待。
- 同步功能:当把一定数量的数据写入管道,管道出现溢出时,写进程便进入阻塞态等待,直到读进程将管道内的数据取走,再唤醒写进程。当管道为空时,读进程进入阻塞态等待,直到写进程向管道写入数据后,再唤醒读进程。
- 确定通信双方是否存在。只有确定了对方已存在时才能进行通信。如果对方已经不存在,就没有再发送或接收消息的必要了。
消息缓冲队列广泛用于本地进程之间的通信。该机制包括数据结构、发送原语和接收原语,每个进程有自己的消息缓冲队列和消息缓冲区。发送进程发送消息时,先申请一个消息缓冲区,将要发送的消息从发送进程的发送区放入消息缓冲区,然后调用发送原语将消息发送给接收进程,发送原语将发送缓冲区插入接收进程的消息缓冲队列。接收消息的进程通过调用接收原语将该进程消息缓冲队列中的消息复制到自己的消息接收区。
内存共享的通信方式,相互通信的进程共享某些数据结构或共享存储区,进程之间能够通过读写共享的内存空间直接进行通信。一个进程通过操作系统将要共享的内存映射到本进程的虚拟内存空间后,具体执行访问内存的操作时可以不通过操作系统,而由地址变换机构实现对共享内存的访问。
套接字进行通信时,通信的发起进程称为客户端,相应进程称为服务器。通信前双方需要建立连接,通信结束后还应该关闭连接。数据传送过程中双方需要同步以保证传输数据的正确性。
注意
- 消息缓冲队列和内存共享方式都通过内存进行通信,所以速度快。但消息缓冲队列要求操作系统内核的参与,每次发送或接收数据都要通过操作系统,而共享内存方式允许进程直接访问共享的数据区,在访问过程中省掉了进入内核等许多费时的环节,因而内存共享是速度最快的通信方式。
- 套接字:客户端和服务器进行连接时,客户端只连接一次(发送connect连接),当我们错误的先打开服务器,再打开客户端,会错失连接机会。此时,我们需要要求服务器一直侦听连接请求,完成连接。(以Qt为例,可以定义QTimer定时器,一直侦听连接请求,直至连接成功,关闭定时器。另Qt中有waitForConnected()函数:等待链接的建立。)
进程通信与线程通信的区别
不同的进程:进程之间相互独立,具有不同的地址空间,必须通过进程间通信机制完成。(管道、消息缓冲队列、共享内存、套接字)
进程的不同线程:共享同一地址空间,可以通过共享内存区域直接通信。(每个线程必须有自己的栈,反映自己特定的执行情况。)
创建进程
申请空白PCB(进程控制块)
为新进程分配资源(包括内存)
初始化进程控制块
新进程插入就绪队列
进程(作业)调度算法
先来先服务调度算法:按照进程到达的先后次序分配CPU。
高响应比优先调度算法:把响应作为一种动态优先权,优先把CPU分配给响应比高的进程。采用该调度算法时,对于等待时间相同,需要服务时间较少的进程,其响应比较高,将优先获得CPU。对于需要服务时间相同的进程,随着等待时间的增加,其响应比也随之增加,优先获得CPU。
- 进程的响应比=(进程等待时间+进程需要的服务时间)/进程需要的服务时间 进 程 的 响 应 比 = ( 进 程 等 待 时 间 + 进 程 需 要 的 服 务 时 间 ) / 进 程 需 要 的 服 务 时 间
时间片轮转调度算法:系统为每个进程分配一个时间片,进程按照进入就绪队列的先后次序轮流在CPU上执行固定的时间片。所有进程都有均等的机会得到运行。
抢占式调度算法:当前正在运行的进行可能被暂停执行,进入就绪队列,CPU可以被系统分配给其他进程。
非抢占式调度算法:一旦进程获得CPU处于执行状态,就一直执行到进程结束,除非因为进程本身的某种原因而自我阻塞。
短作业优先调度算法:优先把CPU分配给短作业,采用该调度算法时,若系统不断有短任务进入就绪队列,长任务可能会因无限等待CPU而进入饥饿状态。
进程的周转时间
- 周转时间=进程完成的时间−进程到达的时间 周 转 时 间 = 进 程 完 成 的 时 间 − 进 程 到 达 的 时 间