【进阶10】【自学笔记】python多进程、多线程、协程详解
一、什么是多进程?
1、进程是指在系统中正在运行的一个应用程序,程序一旦运行就是进程。
2、进程是系统进行资源分配的独立实体, 且每个进程拥有独立的地址空间。
3、一个进程可以拥有多个线程,每个线程使用其所属进程的栈空间。
使用多进程示例:
from random import randint from time import time, sleep from multiprocessing import Process def download_task(filename): print('开始下载%s...' % filename) time_to_download = randint(5, 10) sleep(time_to_download) print('%s下载完成! 耗费了%d秒' % (filename, time_to_download)) def main2(): start = time() p1 = Process(target=download_task,args=("Pytho测试开发入门到精通.pdf",)) p1.start() p2 = Process(target=download_task, args=("Peking Hot.avi",)) p2.start() p1.join() p2.join() end = time() print('总共耗费了%.2f秒.' % (end - start)) if __name__ == '__main__': main2()
运行结果:
两个任务同时执行,总耗时不再是两个任务的时间总和
- Process:通过 Process 类创建进程对象
- target:通过 target 参数传入一个函数名来表示进程启动后要执行的代码
- args:是一个元组,代表传递给函数的参数列表
- start:Process 的 start() 方法来启动进程
- join:Process 的 join() 方法表示等待进程执行结束,才会往下执行
二、什么是多线程?
多线程是指从软件或者硬件上实现多个线程的并发技术
- 多线程的好处:
- 使用多线程可以把程序中占据时间长的任务放到后台去处理,如图片、视屏的下载
- 发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好
使用多线程示例(推荐 threading 模块来实现多线程编程):
#!/usr/bin/env python
from random import randint
from threading import Thread
from time import time, sleep
def download_task(filename):
print('开始下载%s...' % filename)
time_to_download = randint(5, 10)
sleep(time_to_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main2():
start = time()
p1 = Thread(target=download_task,args=("Python测试开发入门到精通.pdf",))
p1.start()
p2 = Thread(target=download_task, args=("Peking Hot.avi",))
p2.start()
p1.join()
p2.join()
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main2()
执行结果:
三、什么是协程?
协程(coroutine)可以理解为是线程的优化,又称之为轻量级进程。它是一种比线程更节省资源、效率更高的系统调度机制。一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。
- 协程的特点:
1、在同时开启的多个任务中,一次只执行一个,只有当前任务遭遇阻塞,才会切换到下一个任务继续执行。这种机制可以实现多任务的同步,又能够成功地避免线程中使用锁的复杂性,简化了开发。
2、极高的执行效率
这里以 asyncio 为例,先来了解一下创建协程所用到的概念:
- event_loop(事件循环):是一个协程处理函数的调用机制。程序会开启一个无限循环,当事件发生时,调用相应的协程函数。
- coroutine(协程对象):指一个使用 async 关键字来定义的函数。调用该函数,会返回一个协程对象。该协程对象就是一个处于挂起状态的协程函数,需要注册到事件循环 event_loop 中,由事件循环 event_loop 进行调用。
- task 任务:是对协程的进一步封装。
- future:等同于 task,代表执行任务的结果。
- async/await 关键字:Python 3.5 中用于定义协程的关键字,其中 async 用于定义一个协程,await 用于挂起阻塞的异步调用接口。
使用协程示例:
import asyncio
from random import randint
from time import time, sleep
#定义协程处理函数
async def download_task(filename):
print('开始下载%s...' % filename)
time_to_download = randint(5, 10)
await asyncio.sleep(time_to_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
#生成协程对象,并传入下载文件
coroutine = download_task("Python测试开发入门到精通.pdf")
coroutine1 = download_task("Peking Hot.avi")
loop=asyncio.get_event_loop() #获得事件循环对象
try:
start = time()
#将协程注册到实现时间循环对象中,并开始运行
loop.run_until_complete(coroutine)
loop.run_until_complete(coroutine1)
end = time()
print('总共耗费了%.2f秒.' % (end - start))
finally:
loop.close()
执行结果:
上面的代码体现了实现协程的基本步骤:
- 使用 async 关键字定义协程处理函数;
- 生成协程对象;
- 调用 asyncio 中的 get_event_loop 函数获得事件循环对象;
- 调用事件循环对象的 run_until_complete 方法,运行协程处理函数
四、总结
应根据业务需要来灵活运用线程或协程或进程。首选多进程+协程的方式。
本文来自博客园,作者:橘子偏爱橙子,转载请注明原文链接:https://www.cnblogs.com/xfbk/p/16094935.html