文章目录
- 计算机内存分配
- 进程与子进程
- 流
- IO模型
- 阻塞IO
- 非阻塞IO
- IO多路复用
- 异步IO
- 网络IO模型
- 简单的socket
- 并发的socket
计算机内存分配
一个32位,4G内存的计算机,内存使用分为两部分:
- 操作系统内核空间;
- 应用程序的用户空间
- 使用的操作系统不同,分配方式不同;
进程与子进程
-
进程
是操作系统中资源管理的最小单位,它是将静态程序加载到内存中的一次动态的执行,包括进程创建、进程调度、进程销毁; -
每个进程有自己独有的内存(在用户空间内),进程的私有内存是相互独立的,且进程间无法直接通信;
-
不同进程间通信,可以采用队列、管道、信号、共享内存(内核空间内)等方式;
-
每个进程中可以创建一个或者多个线程,多个线程共享当前进程的部分内存资源,如代码、全局变量等;
-
进程的内存分布
-
比如上图中的shell脚本,运行时,shell是父进程,python3开启子进程,父进程会等待子进程退出;当关闭shell进程(父进程)时,python3子进程由init进程接管。
-
父进程中,当以fork()系统调用创建子进程时,子进程执行exit()系统调用退出后,内核中仍然存有子进程的信息,如pid, exit code, run time等,这些信息要等父进程通过wait/waitpid来回收,若一直未回收,则退出的子进程成为僵尸进程,一直占用系统资源。
-
僵持进程无法通过kill关闭,随着数量增多,系统资源耗尽,导致系统瘫痪。
流
- 可以进行IO(input输入、output输出)操作的内核对象;
- 如文件、管道、socket…
- 流的入口是fd (file descriptor);
IO模型
-
阻塞IO, 一直等待,不占用资源;无法同时处理多个任务;
用户进程发起读的系统调用,当内核中socket fd未就绪时,一直阻塞等待;
socket fd 就绪时,将内核中的socket数据拷贝到用户空间(拷贝期间阻塞等待);
accept()阻塞
-
非阻塞IO, 忙轮询,占用CPU;
应用程序不断轮询内核,对应的socket fd是否就绪,未就绪则返回(非阻塞);
若已就绪,则拷贝内核中socket的数据到用户空间(阻塞)。
accept()不阻塞
-
IO多路复用,多个IO复用一个进程/线程,既可以阻塞等待不占用资源,又可以同时并发处理多个任务;
- linux 支持select, poll, epoll
- 应用程序通过系统调用让内核同时监控多个socket fd,一旦有网络事件发生,内核就遍历找到对应的socket,将其标记为可读,然后将所有的socket fd返回给应用程序;
- 应用程序遍历所有的fd,找到就绪的fd,通过系统调用复制对应socket的数据到用户空间;
-
异步IO;
-
应用程序发起异步read操作后,立即返回;
-
内核中的fd就绪,复制数据完成,触发信号通知应用程序;
-
全程无阻塞;
-
信号驱动IO
-
首先注册信号处理函数;
-
检查内核socket fd 是否就绪,未就绪直接返回;
-
已就绪,则内核发送信号给应用程序,触发信号处理函数;
-
信号处理函数,发起系统调用,从内核空间拷贝socket数据到用户空间(阻塞);
阻塞IO
pass
非阻塞IO
- 忙轮询,占用CPU;
- 性能不如阻塞IO;
- 代码流程,不停地 遍历所有的fd,查看是否就绪;
IO多路复用
多个IO复用一个进程/线程,既可以阻塞等待不占用资源,又可以同时并发处理多个任务;
- select
- 最大连接数默认1024;
两次拷贝
,先将所有的fd 从用户空间拷贝到内核空间,由内核监控是否有fd就绪(可读或可写),也就是有网络事件发生;一旦有fd就绪,则遍历所有的fd集合,找到对应的fd并将其 标记为就绪态(可读、可写),然后将所有的fd(fd集合)从内核空间拷贝到用户空间,用户进程内遍历所有的fd,找出就绪的从进行读写;两次遍历
;- 并发量大时,性能指数式下降;
- 代码流程:
- poll,与select 没有本质的区别,只是连接数比select多;
- epoll,高性能的IO多路复用(仅linux支持)
- 连接数更大,上限为进程的最大连接数;查看最大连接数cat /proc/sys/fs/file-max
- 内核中采用红黑树结构,可高效地增删改,仅返回就绪的fd;
- 将就绪的fd拷贝给用户进程,避免无用的遍历;
- 适合并发量大的场景,可以解决C10K问题(单台服务器并发1w),
异步IO
网络IO模型
基于socket网络通信
下面以python3语言为例演示socket的使用。
简单的socket
同时只能处理一个客户端的请求。
并发的socket
同时可以处理多个客户端的请求。
- 阻塞+多进程
- 阻塞+多线程
- IO多路复用