多进程简解

作者: 言烬 | 来源:发表于2018-08-20 20:15 被阅读0次

    多进程
    进程:正在执行的应用程序
    多进程:多个运行的应用程序

    Python多进程开发:内建标准模块multiprocessing
    可以通过该模块的Process进程类型,可以很方便的创建和管理多个进程

    常见的multiprocessing属性和模块
    multiprocessing.Process 进程类型,用于创建和管理进程
    multiprocessing.Lock/RLock 进程互斥锁/重用锁, 用于进程同步,数据锁
    multiprocessing.Event 进程事件类型,用于进程同步,数据信号通信
    multiprocessing.Condition 进程条件类型, 用于进程同步, 数据信号通信
    multiprocessing.Queue 进程队列类型,用于多进程数据共享
    multiprocessing.Manager 进程管理类型,专门用于多进程数据共享
    multiprocessing.Listener/Client 进程监听客户端,基于网络多进程之间的数据共享

    多进程的基础操作及面向对象的实现

    #coding:utf-8
    import multiprocessing, os
    
    #基于函数
    def my_proc():
        print("第一个独立的进程,程序的进程编号:", os.getpid(), os.getppid())
    
    def my_proc2(name):
        print(name, "第二个独立的进程,程序的进程编号:", os.getpid(), os.getppid())
    
    
    #基于类型的
    class MyProc(multiprocessing.Process):
    
        def __init__(self, name):
            super().__init__(name=name)
    
        def run(self):
            print(self.name, "基于类型的进程执行", os.getpid(),self.ident, os.getppid())
    
    
    if __name__ == "__main__":
        #创建基于函数的多进程
        p1 = multiprocessing.Process(target=my_proc)
        p2 = multiprocessing.Process(target=my_proc)
        #启动进程
        p1.start()
        p2.start()
    
        #基于函数的,添加参数之后的多进程
        p11 = multiprocessing.Process(target=my_proc2, args=('tom',))#元组中若只有一个元素,则必须带逗号!
        p12 = multiprocessing.Process(target=my_proc2, args=('jerry',))#元组中若只有一个元素,则必须带逗号!
        #启动进程
        p11.start()
        p12.start()
        
        #创建基于类型的多个进程
        p1 = MyProc("进程A")
        p2 = MyProc("进程B")
        #启动进程
        p1.start()
        p2.start()
    

    多进程的简化:内置进程池
    多进程的操作在实际应用中也是非常多的,但是纯底层的代码开发控制并发也是一件非常繁 琐的事情,所以就出现了面向过程多进程并发的优化操作方式:进程池 Pool

    通过进程池 Pool 可以快速创建多个进程执行指定函数,完成高并发处理操作

    """
    进程池
    """
    #引入需要的模块
    import multiprocessing, os, time
    
    #创建程序函数
    def my_proc():
        print(multiprocessing.current_process().name, "一个进程正在执行", os.getpid(), os.getppid())
        time.sleep(1)
    
    
    if __name__ == "__main__":
        #创建一个进程池
        pool = multiprocessing.Pool(2)  #同时工作的任务数
    
        #循环任务
        for i in range(20):  #安排的任务数
            pool.apply_async(my_proc)
    
        #停止提交任务
        pool.close()
    
        #独占执行
        pool.join()
    

    简单案例:多进程下载 有了进程池,可以简单完成一个多进程任务下载的操作处理

    #模拟下载:通过多进程的方式执行
    import time
    from multiprocessing import current_process, Pool
    
    def download(url):
        #下载函数
        print(current_process().name, "开始下载数据》》》》", url)
        time.sleep(1)
        print(current_process().name, "下载数据完成《《《")
        time.sleep(1)
        return "下载号的数据"
    
    
    def sava_data(data):
        print("保存下载的数据:", data)
    
    
    if __name__ == "__main__":
        #创建一个进程池
        pool = Pool(5)
    
        #循环下载数据
        for i in range(20):
            pool.apply_async(download, args=("http://baudu.com",), callback=sava_data)
    
        #停止提交任务给进程池
        pool.close()
        #独占
        pool.join()
    

    多个进程通信:multiprocessing.Manager
    不同线程之间的数据通信,涉及到核心的数据共享问题,主要由 PYTHON 中提供的内建模 块 multiprocessing.Manager 类型实现,该类型内置了大量的用于数据共享的操作

    multiprocessing.Manager 常见属性和方法

    Array 内置进程间共享数组类型
    Queue 内置进程间共享队列类型
    list() 内置进程间共享列表类型
    dict() 内置进程间共享字典类型
    Value 内置进程间共享值类型
    Barrier 进程同步类型
    BoundedSemaphore| Semaphore 进程信号量类型
    Lock|RLock 进程互斥锁/重用锁
    Event 进程同步事件类型
    Condition 进程同步条件类型

    import multiprocessing, time, random
    
    #创建一个条件对象
    con = multiprocessing.Condition()
    
    #创建篮子
    basket = list()
    
    def product():
        while True:
            time.sleep(1)
            #上锁
            con.acquire()
    
            if len(basket) > 20:
                print(":篮子满了, 快来吃吧")
                con.wait()
            else:
                #生产一个包子
                _no = random.randint(1, 10)
                print("蒸好了一个包子", _no)
                basket.append(_no)
                con.notify()
    
            #解锁
            con.release()
    
    def consumer():
        while True:
            time.sleep(0.5)
            #上锁
            con.acquire()
    
            if len(basket) <= 0:
                print("吃光了,快上菜吧")
                con.wait()
            else:
                _no = basket.pop()
                print("吃掉了一个包子", _no)
                con.notify()
            #解锁
            con.release()
    
    
    if __name__ == "__main__":
    
        for i in range(5):
            p = multiprocessing.Process(name="生产者" + str(i) + "号", target=product)
            p.start()
    
        for j in range(5):
            c = multiprocessing.Process(name="消费者" + str(j) + "号", target=consumer)
            c.start()
    

    多个进程通信:multiprocessing.Queue
    多个进程之间的通信操作,数据的传递在 PYTHON 中的 multiprocessing 模块中提供了一个 专门用于多进程之间进行数据传递的队列:Queue

    multiprocessing.Queue 常见属性和方法
    put(data [, timeout=None]) 添加一个数据到队列中
    put_nowait(data) 添加一个数据到队列中,非阻塞模式
    get([timeout=None]) 从队列中获取一个数据
    get_nowait() 从队列中获取一个数据,非阻塞模式
    full() 判断队列是否已满
    empty() 判断队列是否已空
    close() 关闭队列
    qsize() 获取队列中的元素数量

    引入需要的模块

    import multiprocessing, time, random
    
    #定义一个队列储存数据
    basket = multiprocessing.Queue(20)
    
    def product():
    
        while True:
            time.sleep(1)
            _no = random.randint(0, 10)
            try:
                basket.put(_no, timeout=1)
                print("生产者生产了一个数据", _no)
    
            except:
                basket.full()
                print("数据框满了")
    
    
    def consumer():
    
        while True:
            time.sleep(0.5)
            try:
                _no = basket.get(timeout=1)
                print("消费者取走了一个数据", _no)
    
            except:
                basket.empty()
                print("数据框空了")
    
    
    if __name__ == "__main__":
        for i in range(2):
            p = multiprocessing.Process(target=product)
            p.start()
    
        for j in range(2):
            c = multiprocessing.Process(target=consumer)
            c.start()

    相关文章

      网友评论

        本文标题:多进程简解

        本文链接:https://www.haomeiwen.com/subject/anfriftx.html