Python 线程&进程与协程

Python线程、进程与协程的区别

1. 线程

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是比进程更小的能独立运行的基本单位。在Python中,线程是通过threading模块实现的。

线程的创建

Python中的线程创建过程非常简单,只需要调用threading模块的Thread方法,并将需要执行的函数作为参数传入即可。下面是一个例子:

import threading

def print_hello():

for i in range(5):

print("Hello")

def print_world():

for i in range(5):

print("World")

thread1 = threading.Thread(target=print_hello)

thread2 = threading.Thread(target=print_world)

thread1.start()

thread2.start()

thread1.join()

thread2.join()

这段代码创建了两个线程,分别执行print_hello和print_world函数,输出结果是交叉的。

线程的同步

由于Python的全局解释器锁(GIL),所以在多线程环境下,同一时间只能有一个线程在执行Python代码。但是线程之间需要共享变量,如果多个线程同时访问同一个变量,就会引发线程安全问题。解决这个问题的方法就是使用线程同步机制,最常见的就是使用Lock。

下面是一个例子:

import threading

num = 0

lock = threading.Lock()

def add_num():

global num

for i in range(1000000):

lock.acquire()

num += 1

lock.release()

thread1 = threading.Thread(target=add_num)

thread2 = threading.Thread(target=add_num)

thread1.start()

thread2.start()

thread1.join()

thread2.join()

print(num)

这段代码创建了两个线程,分别执行add_num函数,这个函数的目的就是让num加1。由于num是共享变量,需要使用Lock来同步线程,最后输出的结果应该是2000000。

2. 进程

进程是资源分配的最小单位,是运行中的程序的一个实例。进程有自己独立的内存空间,每个进程之间是相互独立的。在Python中,进程可以通过multiprocessing模块来创建。

进程的创建

与线程类似,Python中的进程也可以通过传入准备执行的函数来创建。下面是一个简单的例子:

import multiprocessing

def print_hello():

for i in range(5):

print("Hello")

def print_world():

for i in range(5):

print("World")

process1 = multiprocessing.Process(target=print_hello)

process2 = multiprocessing.Process(target=print_world)

process1.start()

process2.start()

process1.join()

process2.join()

这段代码创建了两个进程,分别执行print_hello和print_world函数,输出结果是交替输出。

进程池

由于每个进程都需要占用一定的系统资源,如果需要同时运行大量的进程,可能会导致系统资源不足。为了解决这个问题,Python提供了进程池来管理进程的数量。

下面是一个例子:

import multiprocessing

def print_hello():

for i in range(5):

print("Hello")

def print_world():

for i in range(5):

print("World")

if __name__ == '__main__':

process_pool = multiprocessing.Pool(processes=2)

process_pool.apply_async(print_hello)

process_pool.apply_async(print_world)

process_pool.close()

process_pool.join()

这段代码创建了一个进程池,最多可以执行两个进程,然后使用apply_async方法异步执行print_hello和print_world函数。

3. 协程

协程是一种用户态的轻量级线程,可以在一个线程中执行多个任务,但是不能利用多核资源。Python中的协程可以使用asyncio模块来编写。

协程的创建

协程的创建过程与线程和进程不同,需要使用async和await关键字来定义协程函数。下面是一个简单的例子:

import asyncio

async def print_hello():

for i in range(5):

print("Hello")

await asyncio.sleep(1)

async def print_world():

for i in range(5):

print("World")

await asyncio.sleep(1)

loop = asyncio.get_event_loop()

tasks = [print_hello(), print_world()]

loop.run_until_complete(asyncio.gather(*tasks))

loop.close()

这段代码定义了两个协程函数print_hello和print_world,分别输出Hello和World,每个输出之间间隔1秒。

协程的异步调用

协程最大的优势就是可以实现异步调用,对于IO密集型的任务效果非常好。下面是一个简单的例子:

import asyncio

import aiohttp

async def download(url):

async with aiohttp.ClientSession() as session:

async with session.get(url) as response:

content = await response.text()

return content

loop = asyncio.get_event_loop()

result = loop.run_until_complete(download("http://www.baidu.com"))

print(len(result))

loop.close()

这段代码使用aiohttp库下载了百度首页,并且使用异步调用提高了并发效率。

总结

Python中的线程、进程和协程都有自己的优点和限制,需要根据具体的应用场景来选择。线程因为受到GIL的限制,所以适合IO密集型的任务,进程可以利用多核资源,适合CPU密集型的任务,而协程可以实现高效的异步调用,适合IO密集型的任务。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签