python multiprocessing doc reading - Serbipunk/notes GitHub Wiki
3 way to start a process
spawn
- 父进程启动一个新的Python解释器进程。
- 只会继承那些运行进程对象的 run() 方法所需的资源。父进程中非必须的文件描述符和句柄不会被继承。
- 启动进程相当慢。
- The default on Windows.
multiprocessing.set_start_method('spawn')
fork
- 父进程使用 os.fork() 来产生 Python 解释器分叉。
- 子进程在开始时实际上与父进程相同。
- 父进程的所有资源都由子进程继承。
- 请注意,安全分叉多线程进程是棘手的。 (SHOULD BE AVOIDED)
forkserver
- 程序启动并选择forkserver启动方法时,将启动服务器进程。
- 每当需要一个新进程时,父进程就会连接到服务器并请求它分叉一个新进程
- 分叉服务器进程是单线程的,因此使用 os.fork() 是安全的。没有不必要的资源被继承。
pool.imap_unordered
for i, _ in enumerate(pool.imap_unordered(download_func, video_urls)): # 值得学这一句
sys.stderr.write('\rdownloading %d / %d' % (i + 1, len(video_urls)))
multiprocessing 支持进程之间的两种通信通道
队列
队列是线程和进程安全的
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()
管道
Pipe() 函数返回一个由管道连接的连接对象,默认情况下是双工(双向)。
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello'])
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, 'hello']"
p.join()