介绍多进程及通信实现异步任务的方法需要分成两部分:多进程及通信。在此之前,先了解几个概念:
- 进程:操作系统中正在运行的应用程序,每个进程拥有独立的地址空间,数据栈,以及其他用于跟踪进程执行的辅助数据。进程通常需要相对长的启动时间和占用大量资源。
- 线程:进程内部的一个独立执行单元,每个进程内部可以有多个线程,一个进程至少有一个线程。线程共享进程的地址空间和资源,因此相对轻量级,可以快速启动和结束,但不会拥有独立的地址空间。
- 同步:指协调各个线程之间的通信,以便它们能够协同工作,达成一致。通常有锁机制、信号量等。
- 异步:指执行某些操作时,不会阻碍代码的执行,可以先执行后续的代码。通常有回调函数、协程等。
了解了这些概念,接下来就是具体的步骤了。
多进程
Python的multiprocessing
模块实现了跨平台的多进程支持,可以轻松地创建多个进程并发地执行任务。
创建进程
使用Process
类可以创建一个子进程,例如:
from multiprocessing import Process
def run():
print('running')
if __name__ == '__main__':
p = Process(target=run)
p.start()
p.join()
Process
类的target
参数指定需要执行的函数,start
方法启动子进程,join
方法等待子进程执行结束。在这个示例中,子进程会执行run
函数并输出running
。
进程池
在并发执行大量任务时,用Process
类一个个创建子进程会耗费很多时间和资源,更好的做法是使用进程池。Python的Pool
类可以方便地创建进程池,例如:
from multiprocessing import Pool
def run(i):
print(f'running task {i} in process {os.getpid()}')
if __name__ == '__main__':
p = Pool(processes=5)
p.map(run, range(10))
上面的代码创建了一个进程池,其中有5个进程,在进程池中执行了10个任务。map
方法用于执行可迭代对象中的每个任务,这些任务将按照顺序在不同进程中执行。
进程通信
由于每个进程都有自己的地址空间,因此多个进程之间无法直接共享变量。不过,可以使用Python的多进程队列或管道来实现进程之间的通信。
队列
Python的Queue
模块提供了线程安全的队列,可以用于多个进程之间的通信。例如:
from multiprocessing import Process, Queue
def produce(q):
for i in range(10):
q.put(i)
print(f'producing {i}')
def consume(q):
while True:
data = q.get()
if data is None:
break
print(f'consuming {data}')
if __name__ == '__main__':
q = Queue()
p1 = Process(target=produce, args=(q,))
p2 = Process(target=consume, args=(q,))
p1.start()
p2.start()
p1.join()
q.put(None)
p2.join()
这个示例创建了一个进程生产数据并将其放入队列中,另一个进程从队列中获取数据并消费。
管道
Python的Pipe
类用于创建管道,可以连接两个进程。例如:
from multiprocessing import Process, Pipe
def send(conn):
conn.send('hello')
conn.close()
def receive(conn):
data = conn.recv()
conn.close()
print(data)
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p1 = Process(target=send, args=(child_conn,))
p2 = Process(target=receive, args=(parent_conn,))
p1.start()
p2.start()
p1.join()
p2.join()
这个示例创建了两个进程,其中一个进程向管道发送数据,另一个进程从管道中接收数据并输出。
以上就是Python实现多进程及通信的方法,其中multiprocessing
模块用于创建子进程,Pool
类用于创建进程池,Queue
和Pipe
用于进程之间的通信。