zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    机器学习(深度学习)
    机器学习(六)
    机器学习一-三
    Leetcode 90. 子集 II dfs
    Leetcode 83. 删除排序链表中的重复元素 链表操作
    《算法竞赛进阶指南》 第二章 Acwing 139. 回文子串的最大长度
    LeetCode 80. 删除有序数组中的重复项 II 双指针
    LeetCode 86 分割链表
    《算法竞赛进阶指南》 第二章 Acwing 138. 兔子与兔子 哈希
    《算法竞赛进阶指南》 第二章 Acwing 137. 雪花雪花雪花 哈希
  • 原文地址:https://www.cnblogs.com/qq1207501666/p/6727611.html
Copyright © 2011-2022 走看看