本节大纲
day9 - 线程进程介绍 1. 工作最小单元是线程 2. 应用程序 -> 至少有一个进程 -> 至少有一个线程 3. 应用场景: IO密集型:线程 计算密集型:进程 4. GIL,全局解释器锁。 - 保证同一个进程中只有一个线程同时被调度 - 线程 1. 基本使用 def task(arg): time.sleep(arg) print(arg) for i in range(5): t = threading.Thread(target=task,args=[i,]) # t.setDaemon(True) # 主线程终止,不等待子线程 # t.setDaemon(False) t.start() # t.join() # 一直等 # t.join(1) # 等待最大时间 2. 锁 # 1. 只能有一个人使用锁 # lock = threading.Lock() # 只能开一把 # lock = threading.RLock()# 可以开多把 # 2. 多个人同时使用锁 # lock = threading.BoundedSemaphore(3) # 3. 所有的解脱锁的限制 # lock = threading.Event() # 4. 肆意妄为 # lock = threading.Condition() 3. 线程池 模式一:直接处理 def task(url): """ 任务执行两个操作:下载;保存本地 """ # response中封装了Http请求响应的所有数据 # - response.url 请求的URL # - response.status_code 响应状态码 # - response.text 响应内容(字符串格式) # - response.content 响应内容(字节格式) # 下载 response = requests.get(url) # 下载内容保存至本地 f = open('a.log','wb') f.write(response.content) f.close() pool = ThreadPoolExecutor(2) url_list = [ 'http://www.oldboyedu.com', 'http://www.autohome.com.cn', 'http://www.baidu.com', ] for url in url_list: print('开始请求',url) # 去连接池中获取链接 pool.submit(task,url) 模式二:分步处理 def save(future): """ 只做保存 # future中包含response """ response = future.result() # 下载内容保存至本地 f = open('a.log','wb') f.write(response.content) f.close() def task(url): """ 只做下载 requests """ # response中封装了Http请求响应的所有数据 # - response.url 请求的URL # - response.status_code 响应状态码 # - response.text 响应内容(字符串格式) # - response.content 响应内容(字节格式) # 下载 response = requests.get(url) return response pool = ThreadPoolExecutor(2) url_list = [ 'http://www.oldboyedu.com', 'http://www.autohome.com.cn', 'http://www.baidu.com', ] for url in url_list: print('开始请求',url) # 去连接池中获取链接 # future中包含response future = pool.submit(task,url) # 下载成功后,自动调用save方法 future.add_done_callback(save) - 进程 1. 基本使用 from multiprocessing import Process import time def task(arg): time.sleep(arg) print(arg) if __name__ == '__main__': for i in range(10): p = Process(target=task,args=(i,)) p.daemon = True # p.daemon = False p.start() p.join(1) print('主进程最后...') 2. 进程之间的数据共享 特殊的东西 - Array(‘类型’,长度) - Manager().list() / Manager().dict() 3. 进程池 ================== 结论 ================== IO密集:线程 计算密集:进程 - 协程 pip3 install greenlet 协程永远是一个线程在执行,对线程的一个分片处理。 二次加工: 自定义: select实现 现成 : pip3 install gevent - IO多路复用 监听多个socket对象是否有变化(可读,可写,发送错误) - 示例一: - socketserverIO - IO多路复用 - 线程 - 自定义异步非阻塞的框架 参考博客: 线程、进程、协程: http://www.cnblogs.com/wupeiqi/articles/5040827.html IO多路复用: http://www.cnblogs.com/wupeiqi/articles/5040823.html 本周作业: 服务端:socketserver 用IO多路复用select,使用“伪”并发 客户端: 基本操作: 聊天 上传 尝试: 客户端是否可以用select来实现???