---恢复内容开始---
不使用socketserver模块实现 tcp协议服务端的并发
import socket from threading import Thread s = socket.socket() s.bind(('127.0.0.1', 56984)) s.listen(5) def server_while(conn): while True: try: data = conn.recv(1024) print(data.decode('utf-8')) conn.send(data.upper()) except ConnectionResetError as c: print(c) break conn.close() if __name__ == '__main__': while True: conn, addr = s.accept() t = Thread(target=server_while, args=(conn,)) t.start()
import socket client = socket.socket() client.connect(('127.0.0.1',56984)) while True: client.send(b'sdjflaasdfad') data = client.recv(1024) print(data)
GIL全局解释器锁
ps:python解释器有很多种 最常见的就是Cpython解释器
GIL本质也是一把互斥锁:将并发变成串行牺牲效率保证数据的安全 用来阻止同一个进程下的多个线程的同时执行(同一个进程内多个线程无法实现并行但是可以实现并发)
问 python的多线程没法利用多核优势 是不是就是没有用了? 答 python的多线程到底有没有用需要看情况而定 并且肯定是有用的 一般 多进程+多线程配合使用
GIL的存在是因为CPython解释器的内存管理不是线程安全的
什么是内存管理(代码申请代码释放 相当于 with open close)
垃圾回收机制
1.引用计数:内存中的数据如果没有任何的变量名与其有绑定关系,那么会被自动回收
2.标记清除:当内存快要被某个应用程序占满的时候,会自动触发
3.分代回收:根据值得存活时间的不同,划为不同的等级,等级越高垃圾回收机制扫描的频率越低
继续问 python的多线程没法利用多核优势 是不是就是没有用了?
研究python的多线程是否有用需要分情况讨论
四个任务 计算密集型的
单核情况下
开线程更省资源 (单核的话 进程 和 线程 都可以并发 但是 线程 更省资源)
多核情况下 一次任务 10秒
开进程 10s (进程可以并行 同时运行4个 进程同时计算)
开线程 40s (需要计算4次的时间才能计算完)
四个任务 IO密集型的
单核情况下
开线程更节省资源(都要等 所有线程节省资源)
多核情况下
开线程更节省资源(即使进程可以并行 但是也需要等 而 线程 可以并发 相差不大 所以使用 线程节省资源)
from threading import Thread import time n = 100 def task(): global n tmp = n time.sleep(1) #相当释放了锁 release n = tmp -1 t_list = [] for i in range(100): t = Thread(target=task) t.start() t_list.append(t) for t in t_list: t.join() print(n)
死锁
RLock (from threading import Thread,Lock,RLock) 又叫递归锁
Rlock可以被第一个抢到锁的人连续的acquire和release
每acquire一次锁身上的计数加1
每release一次锁身上的计数减1
只要锁的计数不为0 其他人都不能抢
from threading import RLock,Thread mutex = RLock() class MyThread(Thread): def __init__(self, name): super().__init__() self.name = name def run(self): mutex.acquire() print('{}抢到了锁'.format(self.name)) mutex.acquire() print('{}抢到了锁'.format(self.name)) mutex.acquire() print('{}抢到了锁'.format(self.name)) mutex.acquire() print('{}抢到了锁'.format(self.name)) mutex.release() print('{}释放了锁'.format(self.name)) mutex.release() print('{}释放了锁'.format(self.name)) mutex.release() print('{}释放了锁'.format(self.name)) mutex.release() print('{}释放了锁'.format(self.name)) if __name__ == '__main__': for i in range(10): t = MyThread(i) t.start()
信号量 (信号量可能在不同的领域中 对应不同的知识点 例如Django)
互斥锁:一个厕所(一个坑位)
信号量:公共厕所(多个坑位)
from threading import Semaphore,Thread import time import random sm = Semaphore(5) # 造了一个含有五个的坑位的公共厕所 使用方法和 LOCK一样 生成对象 def task(name): sm.acquire() print('%s占了一个坑位'%name) time.sleep(random.randint(1,3)) sm.release() for i in range(40): t = Thread(target=task,args=(i,)) t.start()
抢到锁的人执行完后走了 马上就会有人来了