• Python多进程


    普通方式开启进程

    from multiprocessing import Process
    import os
    import time
    
    def fun(i):
    
        time.sleep(3)
        with open('text','r') as f:
            count = int(f.read())
            count -= 1
        with open('text','w') as f:
            f.write(str(count))
        print('这是 %s 个子进程,PID为 %s 父进程PID为 %s count:%s'%(i,os.getpid(),os.getppid(),count))
    
    
    
    if __name__ == '__main__':
        p_s = []
        for i in range(5):
            p = Process(target=fun,args=(i,))
            p_s.append(p)
    
        for p in p_s:
            p.start()

    继承的方式开启进程

    from multiprocessing import Process
    import time
    class MyProcess(Process):
        def __init__(self,*args,**kwargs):
            super().__init__(*args,**kwargs)
    
        def run(self):
            print('开启了一个子进程...')
            self.fun()
    
        def fun(self):
            time.sleep(3)
            print('子进程运行了')
    
    if __name__ == '__main__':
    
        p = MyProcess()
        p.start()

    from multiprocessing import Process,Value,Lock
    def get_num(num,lock):
        for i in range(10):
            lock.acquire()# 获取锁
            num.value -= 1
            lock.release() # 释放锁
            print(num.value)
    
    
    
    def put_num(num,lock):
        for i in range(10):
            lock.acquire() # 获取锁
            num.value += 1
            lock.release() # 释放锁
    
            print(num.value)
    
    
    if __name__ == '__main__':
        num = Value('i',10) # Value可以在多个进程之间共享数据
        lock = Lock() # 实例化一个锁
    
        get_p = Process(target=get_num,args=(num,lock))
        get_p.start()
        put_p = Process(target=put_num,args=(num,lock))
        put_p.start()
        get_p.join()
        put_p.join()
        print(num.value)

    信号量

    from multiprocessing import Semaphore,Process
    import time
    def fun(num,lock):
        lock.acquire()
        print('%s进来了。。。'%num)
        time.sleep(1)
        lock.release()
        print('%s出来了....'%num)
    
    
    
    if __name__ == '__main__':
        lock = Semaphore(5) # 相当于实例化了一个锁,但是锁有五把钥匙
        for i in range(50):
            p = Process(target=fun,args=(i,lock))
            p.start()
    from multiprocessing import Event,Process
    import time
    
    
    def signal_lamp(e):
        while True:
            if e.is_set(): # 如果当前事件状态为true那么将,状态改为false阻塞进程,模拟实现红灯亮起状态
                print('红灯凉了..')
                e.clear()# 将event状态改为false
            else:# 如果当前事件状态为false那么将,状态改为true允许进程运行,模拟实现绿灯灯亮起状态
                print('绿灯凉了....')
                e.set()#将event状态改为true
            time.sleep(10)
    
    
    def Car(i,e):
        e.wait() # 如果e.is_set()为false则阻塞在这一步,否则运行
        print('第%s辆车过去了....'%i)
    
    if __name__ == '__main__':
        # Event几种方法:
        
        # event.isSet():返回event的状态值;
        
        # event.wait():
        # 如果
        # event.isSet() == False将阻塞进程;
        # event.isSet() == True 进程正常运行;
        
        # event.set(): 设置event的状态值为True,所有阻塞池的进程激活进入就绪状态, 等待操作系统调度;
        
        # event.clear():恢复event的状态值为False。
        e = Event()
        sl = Process(target=signal_lamp,args=(e,))
        sl.start()
    
        for i in range(10):
            p = Process(target=Car,args=(i,e,))
            p.start()

    生产者消费者模型Queue

    from multiprocessing import Queue,Process
    
    def producer(q):
        for i in range(20):
            q.put('第 %s 个包子' % (i,))
    
    
    def comsumer(q):
        while True:
            info = q.get()
            if not info:
                break
            print('消费:%s'%(info,))
    
    
    if __name__ == '__main__':
        q = Queue(20) # 创建一个队列,队列内部实现了锁机制,所以在进程中共享数据是安全的
        p_p = Process(target=producer,args=(q,))
        p_c = Process(target=comsumer,args=(q,))
    
        p_p.start()
        p_c.start()
        p_p.join() # 等待生产者完成
        q.put(None)# 如果生产者完成了生成,则在队列中存入None如果,消费者读取到None则退出

    生产者消费者模型JoinableQueue

    from multiprocessing import Process,JoinableQueue
    
    def producer(q):
        for i in range(20):
            q.put('第 %s 个包子' % (i,))
        q.join() # 阻塞,一直阻塞到消费者消费完所有包子(队列中记录了生产的包子个数)
    
    def comsumer(q):
        while True:
            info = q.get()
            print('消费:%s'%(info,))
            q.task_done()# 每消费完一个包子,就会发送一个信号到队列。
            
    
    
    
    
    if __name__ == '__main__':
        q = JoinableQueue(20)
    
        p_p = Process(target=producer,args=(q,))
        p_c = Process(target=comsumer,args=(q,))
    
        p_p.start()
        p_c.daemon = True # 将消费者进程设置为守护进程,那么当主进程的代码全部执行完毕,则会退出消费者进程
        p_c.start()
        p_p.join()  # 主进程等待生产者进程完成
        '''
        这段代码的中心思想:
        首先:生产者进程q.join()会等待消费者吃完所有包子之后才会结束
        然后:主进程 p_p.join() 会等待生产者进程结束
        最后:p_c.daemon = True 会等待主进程结束,然后结束
        
        导致的结果:消费者吃完所有包子 -> 生产者进程结束 -> 主进程代码执行完毕 -> 消费者进程(守护进程)结束
        
        '''

    管道

    from multiprocessing import Process,Pipe
    
    def producer(con):
        con1,con2 = con
        con2.close()
        for i in range(20):
            con1.send('第 %s 个包子' % (i,))
    
    
    def comsumer(con):
        con1, con2 = con
        con1.close()
        while True:
            try:
                info = con2.recv()
            except EOFError:
                con2.close()
                break
    
            print('消费:%s'%(info,))
    
    if __name__ == '__main__':
        # 管道内部没有实现锁机制,需要自己实现。所以管道在多进程中共享数据是不安全的
        con1,con2 = Pipe() # 管道的核心,如果是con1发送,那么只能用con2接收
        p_p = Process(target=producer,args=((con1,con2),))
    
        p_c = Process(target=comsumer,args=((con1,con2),))
        p_p.start()
        p_c.start()
        p_p.join()
        con1.close()

    进程池

    from multiprocessing import Pool
    import os
    import time
    def fun(num):
    
        return num + 1
    
    def call_back(num):
        with open('a.txt','a') as f:
            f.write(str(num))
    if __name__ == '__main__':
        pool = Pool(os.cpu_count()+1) # os.cpu_count() 可以计算出当前计算机的核数
        # # map方法 用时:0.2000112533569336
        # start = time.time()
        # res = pool.map(fun,range(100)) # pool.map(函数,可迭代对象) 将可迭代对象中的每一个元素传入函数计算,并且将计算结果返回 res得到一个列表
        # pool.close()  # 想要主进程等待进程池中的任务全部完成。首先得关闭进程池,使新任务无法在放入进程池。之后在使用pool.join()来使主进程阻塞等待
        # pool.join()
        # print(res)
        # print(time.time()-start)
    
    
        # #apply(同步)方法,跟没开多进程一样,一个一个执行 用时 0.15600895881652832
        # start = time.time()
        # for i in range(100):
        #     res = pool.apply(func=fun,args=(i,)) # pool.apply(func=函数,args=(参数,)) 可以得到函数的返回值
        #     print(res)
        # print(time.time()-start)
    
        # apply(异步)方法 用时 0.08100461959838867
        # pool.apply(func=函数,args=(参数,),callback=回调函数)
            #   使用 res.get()可以得到函数的返回值。
            #   回调函数接收一个参数,参数就是func的返回值,自动传参。(回调函数由主进程调用)
        
        # #回调函数的练习 
        # start = time.time()
        # res_l = []
        # for i in range(100):
        #     res = pool.apply_async(func=fun,args=(i,),callback=call_back)
        #     res_l.append(res)
        # pool.close()
        # pool.join()
        # print(time.time()-start)
  • 相关阅读:
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    C语言寒假大作战01
    C语言I作业12—学期总结
    C语言I博客作业11
    C语言I博客作业10
    C语言I博客作业09
    C语言I博客作业08
    c语言||作业01
  • 原文地址:https://www.cnblogs.com/wtil/p/11195600.html
Copyright © 2020-2023  润新知