multiprocessing

Process Pools

1. apply (func[, args[, kwds]])

  • 只能执行1次(只能输入一次参数)
  • 支持多个参数(参数统一为元祖类型)
  • 阻塞(只能等待这行代码执行完,才会执行下面的代码)
  • 返回结果为函数执行结果

2. apply_async (func[, args[, kwds[, callback[, error_callback]]]])

  • 异步,不阻塞(子进程先跑着,会接着执行主进程代码)
  • 返回结果为 AsyncResult, 可查看结果有没有准备好,使用.get()获取结果

3. map (func, iterable[, chunksize])

  • 可多次函数(迭代参数)
  • 目标函数只支持 单参数 输入
  • 阻塞
  • 返回结果为list,顺序与输入的参数迭代器的顺序一致

4. map_async (func, iterable[, chunksize[, callback[, error_callback]]])

  • 异步,不阻塞
  • 返回结果为 AsyncResult

5. imap(func, iterable[, chunksize])

  • 异步,不阻塞
  • 输出为迭代器,不是list,顺序和输入参数一致

6. imap_unordered (func, iterable[, chunksize])

  • 输出为迭代器,乱序

7. starmap (func, iterable[, chunksize])

  • 支持目标函数为多参数:Demo iterable: [(1,2), (3, 4)]

8. starmap_async (func, iterable[, chunksize[, callback[, error_callback]]])

  • 异步,不阻塞

9. close()

  • 关闭池口,不允许再向池内添加任务
  • 所有任务完成后,子进程都将自动退出

10. terminate()

  • 立即终止某个子进程

11. join()

  • 等待所有子进程完成后,退出

Example

from multiprocessing import Pool

def add(a, b):
    return a + b

if __name__ == '__main__':
    with Pool(processes=4) as pool:
        results = pool.starmap_async(add, [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10), (11, 12), (13, 14)])
        while not results.ready():
            # Do other work while waiting for results
            pass
        output = results.get()
        print(output)

Lock

from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    try:
        print('hello world', i)
    finally:
        l.release()

if __name__ == '__main__':
    lock = Lock()

    for num in range(10):
        Process(target=f, args=(lock, num)).start()

进程间通信

队列 Queue

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

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

返回的两个连接对象 Pipe() 表示管道的两端。每个连接对象都有 send() 和 recv() 方法(相互之间的)。请注意,如果两个进程(或线程)同时尝试读取或写入管道的 同一 端,则管道中的数据可能会损坏。当然,在不同进程中同时使用管道的不同端的情况下不存在损坏的风险。

posted @ 2023-06-16 17:39  shendawei  阅读(11)  评论(0编辑  收藏  举报