目录python
TCP协议就相似于打电话 只有在TCP协议中才会出现粘包现象,由于TCP协议是流式协议 它的特色是将数据量小而且时间间隔比较短的数据一次性打包发送出去 本质其实仍是由于咱们不知道须要接收的数据的长短
1 发送数据直接先告诉对方数据量的大小 2 利用struct模块定制咱们本身的消息传输协议
客户端: 1.制做字典的报头(固定4个长度) 2.发送报头 3.发送字典 4.最后再发真实数据 服务端: 1.先接收4个长度的报头 2.解析报头获取字典的长度 3.接收字典数据 从字典中获取真实数据的详细信息 4.接收真实数据
UDP协议就相似于发短信 1.udp协议客户端容许发空 2.udp协议不会粘包 3.udp协议服务端不存在的状况下,客户端照样不会报错 4.udp协议支持并发 UDP叫数据报协议,意味着发消息都带有数据报头 udp的server不须要就行监听也不须要创建链接 在启动服务以后只能被动的等待客户端发送消息过来,客户端发送消息的时候,要带上服务端的地址 服务端在回复消息的时候,也须要带上客户端的地址
解决cpu在执行程序,遇到io时,不干活的状况 时间上的复用(单个cpu的电脑上,起多个应用程序。cpu快速切换,给人的感受是同时运行) 空间上的复用(多个程序共一套硬件设备,它是多道技术实现时间上的复用的基础,否则还要去硬盘读数据) 一个任务占用cpu时间过长或被操做系统强行剥夺走cpu的执行权限(比起串行效率反而下降) 一个任务执行过程当中遇到io操做,也会被操做系统强行剥夺走cpu的执行权限(比起串行效率提升)
串行:一个程序完完整整的运行完毕,才能运行下一个程序 并发:看上去像同时运行
程序:一堆代码 进程:正在运行的程序 进程是一个实体,每个进程都有它本身独立的内存空间
同步:提交任务以后原地等待任务的返回结果,期间不作任何事! 异步:提交任务以后,不等待任务的返回结果,执行运行下一行代码!
阻塞:遇到io操做 >>> 阻塞态 非阻塞:就绪或者运行态 >>> 就绪态,运行态
会将并发变成串行,牺牲了效率可是保证了数据的安全 锁必定要在主进程中建立,给子进程去用 解决多个进程操做同一份数据,形成数据不安全的状况 加锁会将并发变成串行 锁一般用在对数据操做的部分,并非对进程全程加锁 一把锁不能同时被多我的使用,没有抢到的人,就一直等待锁释放
生产者:生产数据(作包子的) 消费者:处理数据(吃包子的) 二者之间的通讯介质:队列/管道 供需不平衡: 队列: 生产者生产的数据放到队列里面 消费者去队列里面获取数据
进程间通讯 进程与进程之间是数据隔离的 管道/队列(管道+锁) 队列:先进先出 堆栈:先进后出 q.put() 放入值 q.get() 获取队列里面的值(同一时刻只能有一个任务来队列中获取数据) 二者在存放值和取值的时候都会出现阻塞的状况(队列满了,队列空了)
把操做系统比喻成工厂 进程:资源单位(工厂里面的车间) 线程:执行单位(车间里面的流水线) 任何一个进程都自带一个"主"线程 进程中的线程数据是共享的, 开起进程的开销要远远大于开启线程的开销 开启进程:申请空间,拷贝代码都须要耗时 开启线程:开销极小,几乎在代码执行的同时线程就已经建立
线程之间数据共享 多个线程操做同一份数据???出现数据不安全的状况 涉及到多个线程或进程操做同一份数据的时候,一般都须要将并行并发变成串行 虽然牺牲了效率可是提升了数据的安全性 针对不一样的数据,须要加不一样的锁 锁(独立卫生间)
只在Cpython解释器中 因为Cpython内存管理不是线程安全的! 同一进程下的多个线程在同一时刻只能有一个线程被执行 必须先抢解释器才能被cpu执行 GIL是加在Cpython解释器上的一把锁,并不能保证数据的安全,想保证数据的安全,就必须加不一样的锁
内存管理>>>垃圾回收机制 1.引用计数 2.标记清除 3.分代回收
即使你记住了每acquire一次就release一次的操做,也会产生死锁现象 递归锁:能够连续的acquire(),每acquire()一次计数加一
若是把互斥锁比喻成独立卫生间,那么信号量就至关于多个卫生间,一个能够指定多个线程访问
event = Event() event.set() # 告诉另一个子线程 你能够运行了 event.wait() # 等待别人给我发set()信号
固定的ip和port 24小时提供服务 可以实现并发
线程不可能无限制的开下去,总要消耗和占用资源 进程池线程池概念:硬件有极限,为了减轻硬件压力,因此有了池的概念 池: 为了减缓计算机硬件的压力,避免计算机硬件设备崩溃 虽然减轻了计算机硬件的压力,可是必定程度上下降了持续的效率 进程池线程池: 为了限制开设的进程数和线程数,从而保证计算机硬件的安全 - concurrent.futures模块导入 - 线程池建立(线程数=cpu核数*5左右) - submit提交任务(提交任务的两种方式) - 异步提交的submit返回值对象 - shutdown关闭池并等待全部任务运行结束 - 对象获取任务返回值 - 进程池的使用,验证进程池在建立的时候里面固定有指定的进程数 - 异步提交回调函数的使用
- 进程:资源单位 - 线程:执行单位 - 协程:单线程下实现并发(可以在多个任务之间切换和保存状态来节省IO),这里注意区分操做系统的切换+保存状态是针对多个线程而言,而咱们如今是想在单个线程下本身手动实现操做系统的切换+保存状态的功能 协程这个概念彻底是程序员本身想出来的东西,它对于操做系统来讲根本不存在。操做系统只知道进程和线程。 注意: 并非单个线程下实现切换+保存状态就能提高效率,由于你多是没有遇到io也切,那反而会下降效率
将单个线程的效率提高到最高,多进程下开多线程,多线程下用协程>>> 实现高并发!!!
连接和通讯都是io密集型操做,咱们只须要在这二者之间来回切换其实就能实现并发的效果 服务端监测连接和通讯任务,客户端起多线程同时连接服务端