Python的进程、线程和协程

多线程

理解

在Python中,多线程允许程序同时执行多个任务。他是通过创建线程并将任务分配给不同的线程来实现的,这有助于提高程序的执行效率,特别是在执行多个IO操作的时候,不过由于python的解释器锁(GIL),在执行cpu密集型任务的时候,多线程可能不会带来性能的提升

应用场景

多线程经常用于IO密集型的任务,比如网络请求,文件读写等,例如在开发一个网络爬虫的时候,可以使用多线程同时下载多个网页,这样可以减少等待的IO操作的时间,提高程序的运行效率

示例

import threading
import requests

def download_url(url):
    print("开始 下载")
    response = requests.get(url)
    print("下载 结束")

urls = [
    "http://www.example.com",
    "http://www.example1.com",
    "http://www.example2.com",
    "http://www.example3.com",
    "http://www.example4.com",
    ]

thread_s = [threading.Thread(target=download_url, args=(url,)) for url in urls]
for thread in thread_s:
    thread.start()

for thread in thread_s:
    thread.join()

print("所有任务下载完成")

多进程

理解

多进程与多线程类似,也是并发执行的以中方式,但是每个进程都有自己独立的内存空间,因此进程间的通信要比线程间的通信要负责。多进程可以充分利用多核的CPU的优势,因此每个进程可以在不同的cpu核心上

应用场景

多进程用于cpu密集型任务的计算,比如复杂的计算和数据处理。在数据分析科学计算等大量计算的资源应用当中,采用多进程可以有效提升程序的处理速度

示例

from multiprocessing import Pool

def square(x):
    return x * x 

if __name__ == "__main__":
    with Pool(4) as p:
        numburs = range(10000)
        result = p.map(square, numburs)
    print(f'计算结束,{result}')

协程

理解

协程是以中比线程更加轻量级的执行单元,他是通过异步编程的模式来实现并发,协程依赖于时间循环,通过任务的挂起和回复来切换,这种模式非常适合执行IO密集型的操作,因为它可以在等待IO操作完成时,执行其他的任务,从而提高程序的运行效率

应用场景

通常处理大量的网络连接,如在开发高性能的网络服务器或者异步web应用的时候。他允许单个线程高效管理和处理成千上万的并发连接,是实现高并发网络应用的理想选择

示例

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession as session:
        async with session.get(url) as response:
            print("下载完成")

async def main():
    urls = [
        "http://www.example.com",
        "http://www.example1.com",
        "http://www.example2.com",
        "http://www.example3.com",
        "http://www.example4.com",
        ]
    tasks = [fetch(url) for url in urls]
    await  asyncio.gether(*tasks)

asyncio.run(main())

线程和协程的关系

线程

线程是操作系统能够运算调度的最小的单位,他被包含在进程之中,是进程中的实际运作单位,每个线程都是独立调度和分派的基本单位,并且每个线程之间可以独立执行。操作系统调度器是负责管理线程的调度,这可能导致上下文切换的开销。

协程

在Python中,是一种用户态的轻量级线程,由程序自身控制而非操作系统。协程依赖于异步边城,允许任务在等待IO操作的时候挂起,转而执行其他的任务。协程的调度完全由应用程序控制,减少了上下文切换的开销,但他们在一个线程内部执行。

为什么还需要多线程或者多进程

尽管协程提供了搞笑的并发执行的能力,特别是在IO密集型任务的中,但多线程和多进程任然非常重要

CPU密集型任务

对于需要大量计算的任务,多进程可以很好的利用多核cpu的计算能力。因为Python的全局解释器锁限制了同一时刻只能有一个线程执行python字节码,所以在CPU密集型任务中,使用多进程比使用协程或者多线程更能有效的提高程序的性能

遗留系统和库的兼容性

很多现存的系统和库是基于线程模式设计的,对这些系统进行爱写以适应协程模型可能代价高昂。因此,在许需要与这些系统交互的时候,多线程任然是必须的。

简化复杂的任务管理

在某些情况下,使用线程或进程可以简化任务的管理和编程模型。比如,对于并发执行的独立任务,直接创建多个进程或者多个线程可能比协程调度更直观更容易管理

技术栈和场景的多样性

不同的技术栈和应用场景有不同的最佳时间。例如图形界面程序更倾向于使用多线程来避免界面冻结,而高并发的网络服务可能会从协程中收益圣多。

你可能感兴趣的:(python)