网络编程篇:进程、线程、协程、IO模型补充学习

一、进程、线程、协程

# 进程:进程就是一个程序在内存中的运行,进程是资源分配的最小单位
# 线程:线程是cup调度的最小单位
# 计算:消耗cpu,cpu进行运算     
# io:  不消耗cpu
# 垃圾回收机制:垃圾回收线程专门干这个事,一个进程下多线程情况下,使用GIL,只有获得gil锁的线程才能执行
# 正常来讲,如果一个进程开个4个线程,4核cpu,也只有一个核在运行python,原因在于只有拿到GIL锁才能运行
# 开启多进程,充分利用cpu:   
计算密集型使用多进程,io密集型使用多线程
# 线程间变量共享----》多线程并发操作问题----》锁
# 多进程之间变量不共享----》进程间通信问题---》IPC---》进程queue,redis,消息队列

计算2s,计算3s,计算2s
计算2s,计算3s,计算2s
2+3+2+2+3+2


计算用2s,io用3s,计算2s 计算用2s,io用3s,计算2s
2+3+2+2+3+2
2+2+1+2+2

# 并发和并行
    -一个时间段内,多个任务在执行---》可以是一核,可以是多核
    -同一时刻,多个任务在执行----》一定是多核cpu

# 线程间切换,是操作系统决定的,耗费资源
# 程序员自己控制任务的切换,协程,既有IO也有计算可以使用协程效率更高

二、阻塞与非阻塞

# https://www.cnblogs.com/xfeiyun/p/15882626.html
# io操作:数据复制的过程中不会消耗CPU
1 内存分为内核缓冲区和用户缓冲区
2 用户的应用程序不能直接操作内核缓冲区,需要将数据从内核拷贝到用户才能使用
3 而IO操作、网络请求加载到内存的数据一开始是放在内核缓冲区的

# BIO – 阻塞模式I/O
用户进程从发起请求,到最终拿到数据前,一直挂起等待; 数据会由用户进程完成拷贝
'''
举个例子:一个人去 商店买一把菜刀,
他到商店问老板有没有菜刀(发起系统调用)
如果有(表示在内核缓冲区有需要的数据)
老板直接把菜刀给买家(从内核缓冲区拷贝到用户缓冲区)
这个过程买家一直在等待

如果没有,商店老板会向工厂下订单(IO操作,等待数据准备好)
工厂把菜刀运给老板(进入到内核缓冲区)
老板把菜刀给买家(从内核缓冲区拷贝到用户缓冲区)
这个过程买家一直在等待
是同步
'''

# NIO – 非阻塞模式I/O
用户进程发起请求,如果数据没有准备好,那么立刻告知用户进程未准备好;此时用户进程可选择继续发起请求、或者先去做其他事情,稍后再回来继续发请求,直到被告知数据准备完毕,可以开始接收为止; 数据会由用户进程完成拷贝
'''
举个例子:一个人去 商店买一把菜刀,
他到商店问老板有没有菜刀(发起系统调用)
老板说没有,在向工厂进货(返回状态)
买家去别地方玩了会,又回来问,菜刀到了么(发起系统调用)
老板说还没有(返回状态)
买家又去玩了会(不断轮询)
最后一次再问,菜刀有了(数据准备好了)
老板把菜刀递给买家(从内核缓冲区拷贝到用户缓冲区)

整个过程轮询+等待:轮询时没有等待,可以做其他事,从内核缓冲区拷贝到用户缓冲区需要等待
是同步io

同一个线程,同一时刻只能监听一个socket,造成浪费,引入io多路复用,同时监听读个socket
'''

三、IO多路复用

#  IO Multiplexing - I/O多路复用模型
类似BIO,只不过找了一个代理,来挂起等待,并能同时监听多个请求; 数据会由用户进程完成拷贝
# 什么是IO多路复用?
IO 多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;
一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;
没有文件句柄就绪就会阻塞应用程序,交出CPU。

### select poll epoll
#  1 select poll 和epoll都是io多路复用技术
select, poll , epoll都是io多路复用的机制。I/O多路复用就是通过一种机 制个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select, poll , epoll本质上都是同步I/O ,因为他们都需要在读写事件就绪后自己负责进行读写, 也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异 步I/O的实现会负责把数据从内核拷贝到用户空间。

# 2 select
select函数监视的文件描述符分3类,分别是writefds、readfds、和 exceptfds。调用后select函数会阻塞,直到有描述副就绪(有数据可读、 可写、或者有except),或者超时(timeout指定等待时间,如果立即返回 设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来 找到就绪的描述符。
select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个 优点。select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024 ,可以通过修改宏定义甚至重新编译内核的 方式提升这一限制,但是这样也会造成效率的降低。
# 3 poll
不同于select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现。
pollfd结构包含了要监视的event和发生的event,不再使用select '参数-值'传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后 性能也是会下降)。和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
从上面看,select和poll都需要在返回后,通过遍历文件描述符来获取 已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降

# 4 epoll
epoll是在linux2.6内核中提出的,是之前的select和poll的增强版本。相对 于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文 件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。

# 5 更好的例子理解
老师检查同学作业,一班50个人,一个一个问,同学,作业写完了没?select,poll
老师检查同学作业,一班50个人,同学写完了主动举手告诉老师,老师去检查 epoll

# 6 总结
在并发高的情况下,连接活跃度不高,epoll比select好,网站http的请求,连了就断掉
并发性不高,同时连接很活跃,select比epoll好,websocket的连接,长连接,游戏开发

四、并发并行,同步异步,阻塞非阻塞

# 1 并发
并发是指一个时间段内,有几个程序在同一个cpu上执行,但是同一时刻,只有一个程序在cpu上运行
跑步,鞋带开了,停下跑步,系鞋带
# 2 并行
指任意时刻点上,有多个程序同时运行在多个cpu上
跑步,边跑步边听音乐
# 3 同步:
指代码调用io操作时,必须等待io操作完成才返回的调用方式
# 4 异步
异步是指代码调用io操作时,不必等io操作完成就返回调用方式
# 6 阻塞
指调用函数时候,当前线程被挂起
# 6 非阻塞
指调用函数时候,当前线程不会被挂起,而是立即返回

# 区别:
同步和异步是消息通讯的机制
阻塞和非阻塞是函数调用机制
posted @ 2022-08-22 20:35  马氵寿  阅读(46)  评论(0编辑  收藏  举报