云服务器

Swoole入门(6)☞理解同步&异步、阻塞&非阻塞、进程间通信

2017-12-25 11:27:20 0

如何理解程序中的同步/异步?

同步
当一个程序发起调用的时候,在程序没有处理完成返回结果时,调用方会一直等待,等待结果的返回。
异步
当一个程序发起调用的时候,程序立即返回调用成功的消息,但不会马上返回结果,而是需要通过回调的方式把返回结果返回给调用方。
同步/异步实例:
举个生活中的例子,当快递员跟我说你有一份快递,麻烦到楼下取件,但是我还没这么快到,我接到电话之后就一直在楼下等快递,这就是同步。

如果我接到电话的时候,跟他说你到楼下的时候再给我一个电话,我再下楼去拿,这就是异步,快递员第二次打电话给我的过程就叫回调过程。

如何理解程序中的阻塞/非阻塞?

阻塞
阻塞就是在程序调用之后,结果返回之前,当前的进程/线程是被挂起的,上一篇文章也说过,进程是程序的一次执行过程中的一个状态,强调的是当前状态,通俗的来说阻塞就是冻结当前进程的状态
非阻塞
而非阻塞是指程序调用之后,结果返回之前,不会挂起该进程/线程的。
阻塞/非阻塞实例:
举刚才的例子继续说,当你收到快递员的电话的时候,发现是一份很重要的快递,此时此刻什么事情都做不了,这就是阻塞了,处于一个蒙蔽的状态

如果你接到电话后,在快递到楼下之前继续听歌玩游戏,这就是非阻塞了。

同步/异步 和 阻塞/非阻塞的区别?

两者最大的区别就是注重方面不一样,同步/异步注重的是消息通信的方法、手段;而阻塞/非阻塞注重的是状态、状态、状态

进程间通信 => 管道

1.我们知道进程直接是相互独立的,那如果在进程之间通信就需要通过特殊介质,建立管道是其中一种方式。

2.管道分无名管道(pipe)和有名管道(FIFO),无名管道只能用于父子进程或者兄弟进程这些具有亲缘关系的进程;为了克服这个缺点,就有了有名管道,提供非亲缘关系直接进程间通信,这里只讲解无名管道

3.管道特点

顾名思义,管道,就像一条水管一样,同一时刻只能在一个方向上流动;同时遵循队列特点,先进先出的规则。

管道存放在内存中

管道没有名字,只能在具有公共祖先的进程,比如父子进程。

4.管道流程

1.从上图可以看到,这种访问方式是典型的“生产者——消费者”模型。

2.生产者写数据,传至管道缓冲区末尾处,然后消费者从缓冲区头部开始读取。

3.要知道管道缓冲区是否大小限制的,当缓冲区满了,此时生产者得停止写数据了,或者生产者根本没有数据可写了,生产者挂起变成阻塞(睡眠)状态;同理当管道缓冲区没有数据可读了,消费者就会挂起变成阻塞(睡眠)状态,这种状态得改变就叫阻塞I/O事件

4.因为管道是半双工特质,要想实现双方通信,就需要再建立起一个管道实现了。

进程间通信 =>信号

1.比如我们kill命令来杀死一个进程,就是内核生成一个信号,当系统捕获到是这个信号就会做出相应得操作。

2.信号可以作为进程间通信或修改行为的一种方式,明确地由一个进程发送给另一个进程。一个信号的产生叫生成,接收到一个信号叫捕获;上述管道流程中当管道容量满得时候,会发出事件让生产者挂起,而这个事件就叫信号。

select和epoll

在阻塞I/O模式下,当有数据写入如何将生产者中睡眠状态唤醒。

也有人说我们可以写个程序,只要不停的把所有流从头到尾一直循环检出。这样就可以处理多个流了,但这样的做法显然不好,因为如果所有的流都没有数据,那么只会白白浪费CPU。

为了避免CPU空转,可以引进了一个代理select。select可以同时观察所有流的I/O事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中醒来,于是我们的程序就会轮询一遍所有的流。

select仅仅知道了,有I/O事件发生了,但却并不知道是那几个目标流,只能轮询一遍所有流,找出能读出数据,或者写入数据的流,对他们进行操作。随着流越来越多,每次轮询时间就会很长了;而epoll(IO多路复用技术)这个代理知道哪些流发生了I/O事件,然后把目标流通知给我们,大大节省了时间

结语

讲了这么多概念,不知道读者有没有晕倒,^ ^;接下来就进入实战环节了,子进程创建
 
上一篇: 无

微信关注

获取更多技术咨询