Python3-multiprocessing模块-多进程

Python3中的multiprocessing模块是一个与threading模块类似,提供生成进程的API

  多进程multiprocessing模块允许程序员充分利用给定机器上的多个CPU(处理器),但注意CPU是不认识进程的,进程更像是一个线程的容器,这也是为啥一个进程至少包含一个线程,但进程有两个缺点:

    1.进程在同一时间只能干一件事,如果想同时干两件事或以上,进程就心有余而力不足了

    2.进程在执行过程中如果被阻塞,比如等待输入,整个进程就会被挂起,无法做后面的操作

import os
import multiprocessing as mp


def process_func(name):
    print("进程ID,%s" % os.getpid())
    print("父进程ID,%s" % os.getppid())
    print("Hello,%s" % name)
    print("--------------------------")

if __name__ == "__main__":
    p = mp.Process(target=process_func, args=("Jet", ))     # 创建进程1
    p2 = mp.Process(target=process_func, args=("Jack",))    # 创建进程2
    p.start()     # 启动进程1
    p2.start()    # 启动进程2
创建多进程实例

进程间的数据交互

  不同进程的内存都是独享的,所以要想实现不同进程间的数据交互,主要有两种方式:

    1.使用multiprocessing.Queue队列,特点是:FIFO(先进先出)同时它也是线程安全的

import multiprocessing as mp
"""
Queue进程间的互相通讯
特点: FIFO(先进先出)  线程安全
"""


def process_func(q):
    print("Hello,%s" % q.get())  # 取数据
    print("Hello,%s" % q.get())
    print("Hello,%s" % q.get())


if __name__ == "__main__":
    que = mp.Queue()
    que.put("Jet is 1")          # 存数据
    que.put("Jack is 2")
    que.put("Judy is 3")
    p = mp.Process(target=process_func, args=(que, ))     # 创建进程
    p.start()     # 启动进程
View Code

    2.使用multiprocessing.Pipe()管道函数,获取两个连接对象来进程通讯,特点是:双向收发

import multiprocessing as mp
"""
Pipes进程间的互相通讯
特点: 利用两个连接对象进行收发通讯
"""


def process_func(conn):
    print("Hello,%s" % conn.recv())    # 接收数据
    print("Hello,%s" % conn.recv())
    print("Hello,%s" % conn.recv())
    conn.send("你好")    # 发送数据
    conn.close()


if __name__ == "__main__":
    front_conn, behind_conn = mp.Pipe()
    front_conn.send("Jet is 1")          # 发送数据
    front_conn.send("Jack is 2")
    front_conn.send("Judy is 3")
    p = mp.Process(target=process_func, args=(behind_conn, ))     # 创建进程
    p.start()     # 启动进程
    p.join()  
    print(front_conn.recv())    # 接收数据
    front_conn.close()
View Code

进程间的数据共享

  能不能让不同的进程之间共享一份数据呢,答案是肯定的,不过就要使用Manager对象了,而且Manager是线程安全的

import multiprocessing as mp
"""
Manager进程间的数据共享
特点: 多个进程之间共享一些数据
"""


def process_func(d, name ):
    d[name] = name

if __name__ == "__main__":
    with mp.Manager() as mgr:
        dt = mgr.dict()
        p = mp.Process(target=process_func, args=(dt, "Jet"))     # 创建进程
        p1 = mp.Process(target=process_func, args=(dt, "Jack"))   # 创建进程
        p1.start()
        p.start()     # 启动进程
        p.join()
        p1.join()
        print(dt)
View Code

进程同步

  如果多个进程的目标为同一个对象时,比如多个进程都要向屏幕输出,那么此时,就要让这些进程变成串行的,怎么办?加锁!

import os
import time
import multiprocessing as mp


def process_func(l, name):
    try:
        l.acquire()
        print("进程ID,%s" % os.getpid())
        print("父进程ID,%s" % os.getppid())
        print("Hello,%s" % name)
        print("--------------------------")
        time.sleep(2)
    finally:
        l.release()

if __name__ == "__main__":
    lock = mp.Lock()
    p = mp.Process(target=process_func, args=(lock, "Jet", ))     # 创建进程1
    p2 = mp.Process(target=process_func, args=(lock, "Jack",))    # 创建进程2
    p.start()     # 启动进程1
    p2.start()    # 启动进程2
View Code

进程池

  进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止

from multiprocessing import Process, Pool
import time


def process_func(i):
    time.sleep(1)
    print(i)
    return i + 100


def callback_func(arg):
    print('-->exec done:', arg)

if __name__ == "__main__":
    pool = Pool(3)
    for i in range(10):
        pool.apply_async(func=process_func, args=(i,), callback=callback_func)  # 异步调用
        # pool.apply(func=Foo, args=(i,))    # 同步调用

    print('end')
    pool.close()
    pool.join()  # 进程池中的进程执行玩在关闭,先close()在 join()
View Code

参考资料

  http://www.cnblogs.com/alex3714/articles/5230609.html

  http://python.usyiyi.cn/translate/python_352/library/multiprocessing.html

原文地址:https://www.cnblogs.com/qq1207501666/p/6727611.html