Python中运行并行任务技巧攻略
在Python中,我们常常需要处理大量的并行任务,例如多个API请求或者多个数据处理等等。本文将讲述Python中运行并行任务的技巧,以及如何使用Python中的各种工具实现并行任务。
多线程与多进程
在Python中,我们可以使用多线程和多进程来实现并行任务。多线程与多进程的区别在于,多线程是在同一进程内创建多个线程以同时执行任务,而多进程是在不同的进程内创建多个进程以同时执行任务。多线程的优势在于在同一进程内共享数据和内存,操作简单,但是不利于多核CPU的利用;而多进程的优势在于任务的并行执行有利于多核CPU的利用,但是多进程间需要使用IPC(Interprocess Communication)机制来共享数据。
Python中的多线程
Python中的多线程API通常有三个:thread模块、threading模块和concurrent.futures模块。其中,thread和threading模块是早期的API,使用起来稍微有些复杂,而concurrent.futures模块是Python3中新添加的API,使用起来更加方便。
1. threading模块
下面是一个使用threading模块的多线程示例:
import threading
import time
def print_time():
for i in range(5):
time.sleep(1)
print("当前时间为:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
t = threading.Thread(target=print_time)
t.start()
t.join()
print("任务已完成")
在这个示例中,我们定义了一个函数print_time
,用来打印当前时间,然后创建了一个线程t,并将线程的target参数设置为函数print_time
。当我们调用线程的start方法时,线程会开始执行print_time
函数。在主线程中,我们使用t.join()
语句来等待线程执行完毕,然后再输出“任务已完成”。
2. concurrent.futures模块
下面是一个使用concurrent.futures模块的多线程示例:
import concurrent.futures
import time
def print_time():
for i in range(5):
time.sleep(1)
print("当前时间为:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
with concurrent.futures.ThreadPoolExecutor() as executor:
future = executor.submit(print_time)
print("任务已完成")
在这个示例中,我们同样定义了一个函数print_time
,然后使用ThreadPoolExecutor类创建一个线程池executor,将函数print_time
提交给Executor,并通过submit方法获取future对象。在主线程中,我们直接输出“任务已完成”。
Python中的多进程
Python中的多进程API包含两个主要的模块:multiprocessing模块和os模块。其中,multiprocessing模块是Python内建的多进程模块,而os模块提供了一些调用系统级进程和线程的函数,使用起来比multiprocessing模块稍微繁琐一些。
1. multiprocessing模块
下面是一个使用multiprocessing模块的多进程示例:
import multiprocessing
import time
def print_time():
for i in range(5):
time.sleep(1)
print("当前时间为:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
if __name__ == '__main__':
p = multiprocessing.Process(target=print_time)
p.start()
p.join()
print("任务已完成")
在这个示例中,我们同样定义了一个函数print_time
,然后创建了一个进程p,并将进程的target参数设置为函数print_time
。当我们调用进程的start方法时,进程会开始执行print_time
函数。在主进程中,我们使用p.join()
语句来等待进程执行完毕,然后再输出“任务已完成”。
2. os模块
下面是一个使用os模块的多进程示例:
import os
import time
def print_time():
for i in range(5):
time.sleep(1)
print("当前时间为:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
pid = os.fork()
if pid == 0:
print_time()
else:
os.wait()
print("任务已完成")
在这个示例中,我们先定义了一个函数print_time
,然后使用os模块的os.fork()
方法创建了一个子进程,并将子进程的pid消息传递给主进程。在子进程中,我们直接调用print_time
方法打印当前时间,在主进程中,我们使用os.wait()
语句等待子进程执行完毕,然后再输出“任务已完成”。
并行任务的实现工具
除了使用多线程和多进程外,Python中还有一些第三方库可以用来实现并行任务,例如Gevent、Greenlet、Asyncio等。下面我们将讲述这些工具的使用方法和注意事项。
1. Gevent
Gevent是一个使用操作系统提供的非阻塞IO模型(非阻塞socket)的Python网络库,它基于Python协程实现高并发请求处理。下面是一个使用Gevent实现的示例:
import gevent
import time
def print_time():
for i in range(5):
time.sleep(1)
print("当前时间为:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
jobs = [gevent.spawn(print_time) for _ in range(5)]
gevent.joinall(jobs)
print("任务已完成")
在这个示例中,我们使用gevent.spawn
方法创建了5个协程,并将它们放在一个列表中。然后调用gevent.joinall
方法等待所有协程执行完毕,再输出“任务已完成”。
2. Greenlet
Greenlet是一个基于协程的并行计算库,它通过以非抢占式方式切换协程来实现并发。下面是一个使用Greenlet实现的示例:
import greenlet
import time
def print_time():
for i in range(5):
time.sleep(1)
print("当前时间为:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
gr2.switch()
def print_message():
for i in range(5):
time.sleep(1)
print("Hello World!")
gr1.switch()
gr1 = greenlet.greenlet(print_time)
gr2 = greenlet.greenlet(print_message)
gr1.switch()
在这个示例中,我们定义了两个函数print_time
和print_message
,分别用来打印当前时间和“Hello World!”。然后创建了两个greenlet实例,并将它们分别赋值给gr1
和gr2
。在主程序中,我们首先启动gr1
执行print_time
,然后在print_time
函数执行完毕后切换到gr2
执行print_message
,之后再切换回gr1
。
3. Asyncio
Asyncio是Python内置的异步IO框架,它使用async/await关键字定义协程。下面是一个使用Asyncio实现的示例:
import asyncio
import time
async def print_time():
for i in range(5):
await asyncio.sleep(1)
print("当前时间为:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
loop = asyncio.get_event_loop()
tasks = [loop.create_task(print_time()) for _ in range(5)]
loop.run_until_complete(asyncio.wait(tasks))
print("任务已完成")
在这个示例中,我们使用async关键字定义了一个协程print_time
。然后使用asyncio.get_event_loop
方法获取事件循环实例,创建5个任务,将它们放在一个列表中,并将任务列表交给asyncio.wait
方法来等待所有协程执行完毕。之后再输出“任务已完成”。
总结
在本文中,我们讲述了Python中运行并行任务的技巧,并给出了多线程、多进程、Gevent、Greenlet、Asyncio等多种工具的示例。这些工具具有各自的优点和适用范围,要根据具体的场景选择适合的工具来处理并行任务。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python中运行并行任务技巧 - Python技术站