多进程与多线程
进程
- 什么是进程
- 进程就是程序执行的载体
- 进程在生活中的应用
- 打开QQ
- 打开微信
- 玩游戏
- 我们打开的每个软件/游戏,执行的每一个Python脚本都是启动一个进程
- 软件(游戏/脚本)===进程
- 进程的口粮
- 每一个进程像人一样需要吃饭,他的粮食就是:CPU和内存
- 多进程
- 同时启动多个软件(进程),多个进程同时在执行程序,他们之间互不干扰,各自执行自己的业务逻辑。
- 多进程的执行方式
线程
- 什么是线程
- 线程和进程的关系
- 进程提供线程执行程序的前提要求,线程在重组的资源配备下,去执行程序。
- 多线程
- 开启一个浏览器进程后,从浏览器(主线程)中创建出多个线程来开启多个页面
- 多线程的执行方式
进程的创建
-
进程的创建模块--multiprocessing
-
函数名 介绍 参数 返回值 Process 创建一个进程 target,args 进程对象 -
函数名 介绍 参数 返回值 start 执行进程 无 无 join 阻塞程序 无 无 kill 杀死进程 无 无 is_alive 进程是否存活 无 bool -
示例代码:
-
import time import os import multiprocessing def work_a(): for i in range(10): print(i, ‘a‘, os.getpid()) time.sleep(1) def work_b(): for i in range(10): print(i, ‘b‘, os.getpid()) time.sleep(1) if __name__ == ‘__main__‘: start = time.time() a = multiprocessing.Process(target=work_a) # a.start() b = multiprocessing.Process(target=work_b) # b.start() print(time.time() - start) # 用for循环创建 for p in (a, b): p.start()
-
-
-
多进程的问题
- 通过进程模块执行的函数无法获取返回值
- 多个进程同时修改文件可能会出现错误
- 进程数量太多可能会造成资源不足,甚至死机等情况。
进程池与进程锁
-
什么是进程池
- 避免了创建于关闭的消耗
-
进程池的创建---multiprocessing
-
函数名 介绍 参数 返回值 Pool 进程池创建 Processcount 进程池对象 -
函数 介绍 参数 返回值 Apply_async 任务加入进程池(异步) func,args 无 close 关闭进程池 无 无 Join 等待进程池任务结束 无 无 -
示例代码:
-
import multiprocessing import os import time def work(count): print(count, os.getpid()) time.sleep(5) if __name__ == ‘__main__‘: pool = multiprocessing.Pool(5) for i in range(20): pool.apply_async(func=work, args=(i,)) time.sleep(20)
-
-
-
进程锁
-
进程锁的用法
-
from multiprocessing import Manager manage=Manager() lock=manage.Lock()
-
函数名 介绍 参数 返回值 acquire 上锁 无 无 release 开锁(解锁) 无 无
-
进程的通信
-
什么是进程的通信
-
队列的创建-multiprocessing
-
函数名 介绍 参数 返回值 Queue 队列的创建 mac_cout 队列对象 -
函数名 介绍 参数 返回值 put 消息放入队列 message 无 get 获取队列消息 无 str
-
线程的创建
-
线程的创建--threading
-
方法名 说明 举例 Thread 创建线程 Thread(target,args)
-
-
线程对象的方法
-
方法名 说明 用法 start 启动线程 start() join 阻塞直到线程执行结束 join(timeour=None) getName 获取线程的名字 getName() setName 设置线程的名字 setName(name) is_alive 判断线程是否存活 is_alive() setDeamon 守护线程 setDeamon(True)
-
-
线程的问题
- 通过线程执行的函数无法获取返回值
- 多个线程同时修改文件可能造成数据错乱
-
示例代码:
-
import time import random import threading lists = [‘python‘, ‘django‘, ‘tronado‘, ‘flask‘, ‘bs5‘, ‘requests‘] new_lists = [] def work(): if len(lists) == 0: return data = random.choice(lists) lists.remove(data) new_data = ‘%s_new‘ % data new_lists.append(new_data) time.sleep(1) if __name__ == ‘__main__‘: start = time.time() t_list = [] for i in range(len(lists)): t = threading.Thread(target=work) t_list.append(t) t.start() for t in t_list: t.join() print(‘old list‘, lists) print(‘new list‘, new_lists) print(‘time is %s‘ % (time.time() - start))
-
线程池的创建
-
线程池---concurrent
-
方法名 说明 举例 futures.ThreadPoolExecutor 创建线程池 tpool=ThreadPoolExecutor(max_workers)
-
-
线程池---concurrent
-
方法名 说明 用法 submit 往线程池中加入任务 submit(target,args) done 线程池中的某个线程是否完成了任务 done() result 获取当前线程执行任务的结果 result()
-
-
示例代码
-
import time import os import threading from concurrent.futures import ThreadPoolExecutor lock = threading.Lock() def work(i): lock.acquire() time.sleep(1) lock.release() return ‘result %s‘ % i if __name__ == ‘__main__‘: print(os.getpid()) t = ThreadPoolExecutor(2) result = [] for i in range(20): t_result = t.submit(work, (i,)) result.append(t_result) for res in result: print(res.result())
-
认识GIL全局锁
- 别家的线程与我家的线程
- Gil的作用
- 单一cpu工作
- 线程安全
- pypy
- 多进程+多线程
初探异步
-
什么是异步与异步的好处
-
异步与多线程多进程
- 轻量级的线程 协程
- 可以获取异步函数的返回值
- 主进程需要异步才行
- 更适合文件读写使用
-
async,await与asyncio模块
-
async定义异步
-
async def test(): return ‘a‘
-
-
await执行异步
-
async def handle(): result = await test()
-
-
-
asyncio调用async函数
-
函数名 介绍 参数 返回值 gather 将异步函数批量执行 Asyncfunc.. List函数的返回结果 run 执行主异步函数 [task] 执行函数的返回结果 -
import asyncio async def main(): result = await asyncio.gather(a(), b()) print(result) if __name__ == ‘__main__‘: asyncio.run(main())
-
-
gevent
- Pip install gevent
- Microsoft Visual C++
- Pip install wheel
-
gevent模块常用方法
-
函数名 介绍 参数 返回值 spawn 创建协程对象 Func,args 协程对象 joinall 批量处理协程对象 [spawnobj] [spawnobj]
-
-
gevent协程对象的方法
-
函数名 介绍 参数 返回值 get(value) 获取异步程序结果 无 函数的返回值 join 阻塞等待异步程序结束 无 无 kill 杀掉当前协程 无 无 Dead 判断协程是否消失 无 bool
-