1. 进程之间通信的途径有哪些?并说一下他们的通信机制原理
进程间通信的途径包括管道、消息队列、共享内存、信号量、套接字等,以下是几种常见的进程间通信方式及原理:
(1) 管道(Pipe)
通信机制原理:管道是一种半双工的通信方式,具有固定的读端和写端,数据通过内核缓冲区在进程间传递,管道分为无名管道和有名管道。无名管道只能用于亲缘关系的进程间通信(如:父子进程),而有名管道可以在无亲缘关系的进程间进行通信,有名管道在文件系统中有一个路径名与之关联,因此可以像操作普通文件一样进行读写操作
(2) 消息队列(Message Queue)通信机制原理:消息队列是两个不相关的进程之间传递数据的一种简单高效的方式,它克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等特点。消息队列在内核中创建一个队列,队列中的每个元素是一个数据报。不同的进程可以通过句柄访问这个队列,并按照顺序或消息类型读取数据。消息队列可以实现双向通信,并且具有独立的发送和接收数据
(3) 共享内存(Shared Memory)通信机制原理:共享内存允许多个进程访问同一块物理内存区域,从而实现高速的数据交换,共享内存通常与其他通信机制(如信号量)配合使用,以确保进程间的同步和互斥访问,通过将同一块物理内存映射到不同进程的虚拟地址空间中,实现进程间的数据共享,这种方式避免了数据的频繁拷贝和内核态与用户态之间的切换,因此具有较高的通信效率
(4) 信号量(Semaphore)
通信机制原理:信号量是一种进程间同步和互斥的机制。它常用于控制进程对共享资源的访问,以防止资源竞争和数据不一致的问题。信号量的值表示可用资源的数量,当信号量的值大于0时,表示有资源可用,当信号量的值为0时,表示资源已被占用。进程在访问共享资源前,需要先对信号量进行 P 操作(减1),访问结束后进行 V 操作(加1)。通过这种方式,可以确保进程间的同步和互斥访问
(5) 套接字(Socket)通信机制原理:套接字是一种进程间通信方式,它可以在不同的计算机之间进行通信。套接字通常用于实现分布式系统和网络通信。套接字起源于 UNIX 系统,它提供了一种“打开— 读/写 — 关闭”模式的实现方式。服务器和客户端各自维护一个“文件”(即套接字),在建立连接后,可以向自己的文件写入内容供对方读取获读取对方的内容。套接字隐藏了复杂的TCP/IP 协议族细节,向用户提供了一种简单的接口用于数据通信
2. 产生死锁的原因是什么?
多个并发进程因争夺系统资源而产生相互等待的现象。即:一组进程中的每个进程都在等待某个事件发生,而只有这组进程中的其他进程才能触发该事件,这就称这组进程发生了死锁
产生死锁的本质原因为:(1) 系统资源有限(2) 进程推进顺序不合理
死锁的4个必要条件是什么?(1) 互斥:资源被某进程独占使用,其他进程需等待
(2) 请求与保持:进程持有部分资源同时请求更多,若请求失败则阻塞,但不释放已持有的资源
(3) 不可抢占:已分配的资源在进程使用完前不能被其他进程抢占
(4) 循环等待:进程间形成资源请求的循环链,每个进程都在等待下一个进程释放资源
3. 什么是进程?什么是线程?进程和线程有什么区别?
进程是具有独立功能的程序关于某一个数据集合上的一次运行活动,进程是资源分配的基本单位,它是程序执行时的一个实例,在程序运行时创建
线程是程序执行的最小单位,是进程的一个执行流,一个进程可以由多个线程组成
(1) 进程是资源分配的基本单位(2) 线程是程序执行的基本单位,也是处理器调度的基本单位,但进程不是,两者均可并发执行(3) 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据,使用相同的地址空间,因此,CPU切换一个线程的花费远比进程小很多,同时创建一个线程的开销也比进程小很多(4) 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也跟着死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间(5) 进程切换时,消耗的资源大,效率低。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程(6) 执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制(7) 线程执行开销小,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。进程执行开销大,但是能够很好的进行资源管理和保护,可以跨机器迁移