操作系统(2)

操作系统(2)

进程间通信方式详细叙述

1、管道如何通信

管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条,管道的一端连接一个进程的输出,另一端连接一个进程的输入。

管道这个缓冲区不需要很大,它被设计成为环形的数据结构,以便管道可以被循环利用。当管道中没有信息的话,从管道中读取的进程会等待,直到另一端的进程放入信息。当管道被放满信息的时候,尝试放入信息的进程会等待,直到另一端的进程取出信息。当两个进程都终结的时候,管道也自动消失。


管道如何创建?

管道利用fork机制(不同进程中的同一个虚拟地址被映射到不同的物理地址)建立,从而让两个进程可以连接到同一个PIPE上。

如下图,最开始的时候,左边一红一黑都连接在同一个进程Process 1上(连接在Process 1上的一红一黑)。当fork复制进程的时候,会将这两个连接也复制到新的进程(Process 2)。随后,每个进程关闭自己不需要的一个连接 ,两个黑色的箭头被关闭,这样,剩下的红色连接就构成了如上图的PIPE。

2、命名管道如何通信

管道只能用于父进程和子进程之间,或者拥有相同祖先的两个子进程之间 ,而命名管道可以让没有亲缘关系的进程之间通信。

命名管道又叫做FIFO (First in, First out)为一种特殊的文件类型,本质是文件。以FIFO的文件形式存储于文件系统中。命名管道是⼀个设备文件,有名字,因此,不相关的进程可以通过打开命名管道进行通信,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问该路径,就能够通过FIFO相互通信。值得注意的是,FIFO(first input first output)总是按照先进先出的原则工作,第⼀个被写入的数据将先从管道中读出。

3、信号量

定义:信号量是一个特殊的变量,用来协调进程对共享资源的访问,确保一个临界区同一时间只有一个线程在访问。

  • 最简单的信号量是只能取0和1的变量,这也是信号量最常见的一种形式,叫做二进制信号量。而可以取多个正整数的信号量被称为通用信号量。
  • 信号量只能进行两种操作:等待和发送信号
  • 举个例子,就是两个进程共享信号量sv,sv=1,第一个进程得到了这个信号量,可以进入临界区域,并使sv减1变为0。第二个进程一看信号量sv=0,就会被挂起以等待第一个进程离开临界区,第一个进程离开临界区的时候会把sv+1。

名词解释:

某些资源同一时间只能被一个进程占用,这些资源叫临界资源。进程内访问临界资源的代码被称为临界区。

消息队列

消息队列就是链表队列

  • 消息队列跟命名管道有不少的相同之处
  • 与命名管道一样,消息队列进行通信的进程可以是不相关、无亲缘关系的进程。
  • 同时它们都是通过发送和接收的方式来传递数据的。
  • 而且它们对每个数据都有一个最大长度的限制。

消息队列优势:

  • 消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  • 除开发送、接收进程,消息队列可以独立存在。管道是发送、接收进程关闭了,管道就自动关闭了。
  • 消息队列,避免了命名管道同步和阻塞问题。
  • 接收可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。

4、signal信号

信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达。

信号的种类

可以从两个不同的分类角度对信号进行分类:

可靠性方面:可靠信号与不可靠信号;

  • 信号分为可靠和不可靠的,早期的信号比较原始,容易丢失,因此不可靠。后期新增了一些信号,这些信号支持排队,不会丢失,直接定义为可靠信号。
  • 信号值小于SIGRTMIN=32都是不可靠信号,信号值位于SIGRTMIN=32和SIGRTMAX=63之间的信号都是可靠的。信号的可靠与不可靠只与信号值有关,与信号的发送及安装函数无关。

与时间的关系上:实时信号与非实时信号。

  • 非实时信号都不支持排队,都是不可靠信号,编号是1-31,0是空信号;实时信号都支持排队,都是可靠信号

信号的发送和安装

  • 发送信号的主要函数有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort()。
  • 如果进程要处理某一信号,那么就要在进程中安装该信号。安装信号主要用来确定信号值及进程针对该信号值的动作之间的映射关系,即进程将要处理哪个信号;该信号被传递给进程时,将执行何种操作。

5、共享内存

共享内存是最有用的、最快的进程间通信方式。是针对其他通信机制运行效率较低而设计的。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。

6、套接字Socket

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个Socket。Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。

分为两种

  • 流式Socket(STREAM):是一种面向连接的Socekt,针对面向连接的TCP服务应用,安全,但是效率低;
  • 数据报式Socket(DATAGAM):是一种无连接的Socket,对应于无连接的UDP服务应用。不安全(丢失,顺序混乱,在接受端要分析重排及要求重发),但效率高。

    

多个进程处理一个Socket(端口)?

计算机上不同服务调用不同的端口(Tomcat和Nginx端口就不一样),同一种服务的不同进程也要用不同的端口(Tomcat集群端口不一样),即一个服务只能用一个端口。但一个端口可以同时连接N多个用户请求。


多个线程处理一个Socket(端口)???

  • 对于UDP,多个线程读写一个Socket不用加锁,当然最好的做法是每个线程有自己的Socket。
  • 对于TCP,多个线程处理一个Socket是错误的设计。

总结:对于UDP,加锁是多余的,对于TCP,加锁是错误的。




全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务