python multiprocessing doc reading - Serbipunk/notes GitHub Wiki

REFERENCE LINK

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()