• Python并发编程


    1 进程的创建与结束

    1.1 multiprocess.process模块

    • process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。
    • 创建一个子进程
    from multiprocessing import Process
    import time,os
    
    def func():
        time.sleep(2)
        print("i am 子进程,pid %s" %(os.getpid()))
    
    
    if __name__ == "__main__":
        p = Process(target=func)
        p.start()
        print("i am 主进程,pid %s" %(os.getpid()))
    
    • join方法的使用,主线程等待子线程终止
    from multiprocessing import Process
    import time,os
    
    def func():
        time.sleep(2)
        print("i am 子进程,pid %s" %(os.getpid()))
    
    
    if __name__ == "__main__":
        p = Process(target=func)
        p.start()
        p.join()
        print("i am 主进程,pid %s" %(os.getpid()))
    •   同时开启多个子进程,并且执行完毕后在主进程
    from multiprocessing import Process
    import time,os
    
    def func():
        time.sleep(2)
        print("i am 子进程,pid %s" %(os.getpid()))
    
    
    if __name__ == "__main__":
        p_list=[]
        for i in range(4):
            p = Process(target=func)
            p.start()
            p_list.append(p)
        for p in p_list:
            p.join()
        time.sleep(1)
        print("i am 主进程,pid %s" %(os.getpid()))
    
    •  进程与子进程数据是隔离的
    from multiprocessing import Process
    import time,os
    
    n=100
    def func(name):
        n=20
        time.sleep(2)
        print("i am 子进程,pid %s,%s,%s" %(os.getpid(),name,n))
    
    
    if __name__ == "__main__":
        p_list=[]
        for i in range(4):
            p = Process(target=func,args=(i,))
            p.start()
            p_list.append(p)
        for p in p_list:
            p.join()
        time.sleep(1)
        print("i am 主进程,pid %s,%s" %(os.getpid(),n))
    
    •   守护进程:会随着主进程的结束而结束。主进程创建守护进程

      其一:守护进程会在主进程代码执行结束后就终止

      其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

    注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

    from multiprocessing import Process
    import time,os
    
    def func(name):
        time.sleep(2)
        print("i am 子进程,pid %s,%s" %(os.getpid(),name))
    
    
    if __name__ == "__main__":
        p = Process(target=func,args=('abc',))
        p.daemon = True
        p.start()
        print("i am 主进程,pid %s" %(os.getpid()))
    
    • 主进程代码执行结束守护进程立即结束
    from multiprocessing import Process
    import time,os
    
    def func1(name):
        time.sleep(1)
        print("i am 子进程,pid %s,%s" %(os.getpid(),name))
    
    def func2(name):
        time.sleep(2)
        print("i am 子进程,pid %s,%s" %(os.getpid(),name))
    
    
    if __name__ == "__main__":
        p1 = Process(target=func1,args=('func1',))
        p2 = Process(target=func2,args=('func2',))
        p1.daemon = True  #p1不会被打出
        p1.start()
        p2.start()
        print("i am 主进程,pid %s" %(os.getpid()))
    
    • 进程锁:当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题。
    • 虽然使用加锁的形式实现了顺序的执行,但是程序又重新变成串行了,这样确实会浪费了时间,却保证了数据的安全
    import os,time
    from multiprocessing import Process,Lock
    
    def fun1(i,lock):
        lock.acquire()
        time.sleep(1)
        print("%s,%s" %(os.getpid(),i))
        lock.release()
    
    
    if __name__ == '__main__':
        lock=Lock()
        for i in range(3):
            p=Process(target=fun1,args=(i,lock))
            p.start()
        print("i am 主进程 %s" %(os.getpid()))
    
    • 模拟抢票需要用到进程锁
    import os,time,json
    from multiprocessing import Process,Lock
    
    def rob_ticket(num,lock):
        lock.acquire()
        ticket_dic=json.load(open("db"))
        time.sleep(0.2)
        print("剩余的票数为%s" %ticket_dic["count"])
        if ticket_dic["count"]>0:
            ticket_dic["count"]-=1
            time.sleep(1)   #模拟网络延迟
            json.dump(ticket_dic,open("db","w"))
            print("%s抢票成功" %num)
        lock.release()
    
    if __name__=="__main__":
        lock=Lock()
        for num in range(5):
            p=Process(target=rob_ticket,args=(num,lock))
            p.start()
    
    • 信号量相当于有多把钥匙和锁
    • 模拟KTV房间人进进出出,房间不是一个
    #!/usr/bin/env python
    import time
    from multiprocessing import Semaphore,Process
    
    def go_ktv(sem,num):
        sem.acquire()
        print("%s现在在ktv唱歌"%num)
        time.sleep(1)
        sem.release()
    
    if __name__ == "__main__":
        sem=Semaphore(3)
        p_l=[]
        for i in range(10):
            p=Process(target=go_ktv,args=(sem,"User%s"%i))
            p.start()
            p_l.append(p)
        for p in p_l:
            p.join()
        print("主进程:没有人在唱歌了")
    

      

      

      

  • 相关阅读:
    Eclipse JSP/Servlet 环境搭建
    1,有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
    Electron-vue实战(二)— 请求Mock数据渲染页面
    Electron-vue实战(一)—搭建项目与安装Element UI
    Electron-vue实战(三)— 如何在Vuex中管理Mock数据
    vue学习笔记(六)— 关于Vuex可以这样简单理解
    vue学习笔记(五)— 组件通信
    OpenLayers学习笔记(十二)— 飞机速度矢量线预测(二)
    QML学习笔记(八)— QML实现列表侧滑覆盖按钮
    重学JavaScript
  • 原文地址:https://www.cnblogs.com/so-cool/p/9177331.html
Copyright © 2020-2023  润新知