• 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("主进程:没有人在唱歌了")
    

      

      

      

  • 相关阅读:
    在windows系统和linux系统中查询IP地址命令的不同
    Linux --忘记root密码/su: Authentication failure
    Spring+quartz集群解决多服务器部署定时器重复执行的问题
    spring定时任务scheduler集群环境下指定运行服务器防止多服务器多次执行
    跨库数据表的运算
    AspectJ 切面注解中五种通知注解:@Before、@After、@AfterRunning、@AfterThrowing、@Around
    JUnit4 中@AfterClass @BeforeClass @after @before的区别对比
    Java后端的学习之Spring基础
    MySQL 5.7默认ONLY_FULL_GROUP_BY语义介绍
    【可靠性】Mysql 5.7 降低了半同步复制-数据丢失的风险
  • 原文地址:https://www.cnblogs.com/so-cool/p/9177331.html
Copyright © 2020-2023  润新知