多进程编程


01.多进程允许在完全独立的进程环境中运行程序,可以充分的利用多处理器。

  • 多进程本身的进程之间隔离会导致数据不能共享,并且进程相比线程更重量级。
  • 多进程更适合于cpu密集形的任务。


02.使用multiprocessing.Process类可以实现多进程。

  • 多进程声明的格式为:
multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={},*, daemon=None)
  • target,目标函数。
  • name,子进程的名称。
  • daemon,父进程结束时是是否同步结束子进程,默认为false。
  • 多进程的简单示例:
import multiprocessing
import logging
import datetime


FORMAT = "%(thread)s %(message)s"
logging.basicConfig(format=FORMAT, level=logging.INFO)
start = datetime.datetime.now()


# 定义一个赋值的函数
def calc():
    sum = 0
    for _ in range(1000000000):
        sum += 1

# 多进程代码一定要放在if __name__ == '__main__'下。
if __name__ == '__main__':

    # 创建一个队列用于存放进程列表
    process_list = []

    for _ in range(4):
        # 使用多进程调用calc函数
        p = multiprocessing.Process(target=calc)
        p.start()
        # 将进程对象添加到队列中
        process_list.append(p)

    for p in process_list:
        # 挂起父进程
        p.join()

    delta = (datetime.datetime.now() - start).total_seconds()
    logging.info(delta)


03.使用multiprocessing.Pool类可以实现进程池。

  • 进程池声明的格式为:
multiprocessing.Pool(processes,initializer,initargs,maxtasksperchild)
  • target,目标函数。
  • name,子进程的名称。
  • daemon,父进程结束时是是否同步结束子进程,默认为false。
  • 进程池的方法包括:
    • apply(),阻塞执行,导致父进程执行其他子进程时串行执行。
      • apply()一旦执行,则当前进程阻塞(不建议使用)。
    • apply_sync(),与apply方法用法一致,非阻塞异步执行,得到结果后会执行回调。
      • apply_sync()有一个callback参数用于回调函数,进程池会将执行的函数的返回值作为参数传递给回调函数。
    • close(),关闭进程池。
    • terminate(),结束工作进程,不再接受新的任务。
    • jon(),父进程阻塞等待子进程的退出,join()要在close()或者terminate()之后使用。
  • 进程池的简单示例:
import multiprocessing
import logging
import datetime


FORMAT = "%(process)d %(processName)s %(thread)s %(message)s"
logging.basicConfig(format=FORMAT, level=logging.INFO)
start = datetime.datetime.now()


# 定义一个赋值的函数
def calc():
    sum = 0
    for _ in range(10000000):
        sum += 1
    return sum


# 定义一个回调函数
def show(x):
    logging.info(x)


if __name__ == '__main__':

    # 创建一个包含4个进程进程池
    pool = multiprocessing.Pool(processes=4)
    for i in range(5):
        # 在进程池中获取一个进程运行函数,并且将函数的返回值作为参数传递给回调函数。
        pool.apply_async(calc, callback=show)

    # 关闭进程池。
    pool.close()
    pool.join()

    delta = (datetime.datetime.now() - start).total_seconds()
    logging.info(delta)
文档更新时间: 2021-10-04 00:19   作者:闻骏