进程调度方式
时间片轮转调度
时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。
参见百度百科: https://baike.baidu.com/item/进程调度/10702294?fr=aladdin
系统需要维护3个队列:
- 1.等待态:等待某个事件的完成;
- 2.就绪态:等待系统分配处理器以便运行;
- 3.运行态:占有处理器正在运行。
运行态→等待态 往往是由于等待外设,等待主存等资源分配或等待人工干预而引起的。
等待态→就绪态 则是等待的条件已满足,只需分配到处理器后就能运行。
运行态→就绪态 不是由于自身原因,而是由外界原因使运行状态的进程让出处理器,这时候就变成就绪态。例如时间片用完,或有更高优先级的进程来抢占处理器等。
就绪态→运行态 系统按某种策略选中就绪队列中的一个进程占用处理器,此时就变成了运行态
IO事件
遇到IO事件,会变成等待态,放入到等待队列。遇到锁也会放入到等待队列
IO多路复用
一个进程可以处理多个IO事件,多个请求。
遇到IO事件进入等待态,会造成一个线程只能处理一个请求,线程过多上下文切换又会浪费cpu,所以有了IO多路复用技术
举例:一个线程利用epoll监听多个fd,将fe、事件注册到epoll中,当有事件发生时,线程再去处理。具体包含:注册、epoll_wait(获取可以处理的fd)、处理、再放回epoll(可能没有处理完)。线程需要维护fd相应的session信息,事件对于的回调函数,当某类事件来临时,可以进行相应处理。
正是因为nginx应用了IO多路复用,所以可以单线程,可以处理高并发的请求
nginx事件处理
nginx是一个master进程,多个worker进程(一个进程包含一个线程)。master进程监听请求之后,转给worker进程处理,由于网络包的传输是一个个分批传输的,worker进程在读取网络IO的时候,不能一次性读取完,一般两种选择 第一阻塞:一直等,等这个连接完全传输完,然后进行相应处理,这样会造成一个线程只能同时处理一个请求,并发低。 第二非阻塞:也是nginx采取的方式,不会一直等,而是转而去处理其他请求。这就是异步非阻塞IO
其他概念
事件驱动:nginx是事件驱动的,事件来了 我才去处理
IO:文件、网络 均为IO事件。 fd是IO的一种抽象