Fork me on GitHub

【进阶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() 方法表示等待进程执行结束,才会往下执行

二、什么是多线程?

多线程是指从软件或者硬件上实现多个线程的并发技术

  • 多线程的好处:
  1. 使用多线程可以把程序中占据时间长的任务放到后台去处理,如图片、视屏的下载
  2. 发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好

使用多线程示例(推荐 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()

  执行结果:

 上面的代码体现了实现协程的基本步骤:

  1. 使用 async 关键字定义协程处理函数;
  2. 生成协程对象;
  3. 调用 asyncio 中的 get_event_loop 函数获得事件循环对象;
  4. 调用事件循环对象的 run_until_complete 方法,运行协程处理函数

四、总结

应根据业务需要来灵活运用线程或协程或进程。首选多进程+协程的方式。

posted @ 2022-04-03 00:13  橘子偏爱橙子  阅读(85)  评论(0编辑  收藏  举报