• 守护进程 互斥锁 进程间通讯


    1. 守护进程:
    from multiprocessing import Process
    import time
    def task():
    print("11111111111111")
    time.sleep(3)
    print("222222222222")

    if __name__ == '__main__':
    p=Process(target=task)
    p.daemon=True#p是主进程的守护进程
    p.start()
    print("3333333333")
    print("4444444444")
    #守护进程在被守护进程死亡时会随之死亡
    #注意:p.daemon=True必须在启动进程前执行

    2.互斥锁*****

    当多个进程 同时读写同一份数据 数据很可能就被搞坏了。并发式读写会导致文件最后无法解码.(并发无法控制进程顺序)
    目前可以使用join来将所有程序并发改成串行
    多个进程并发的访问了同一个资源 将导致资源竞争(同时读取不会产生问题 同时修改才会出现问题)

    第一个方案 加上join 但是这样就导致了不公平 相当于火车进站无论什么时间开的都必须按照队伍来,不能紧急通行
    第二个方案 加锁 谁先抢到资源谁先处理

    相同点:都编程了串行
    不同点:join顺序是固定的 加锁的顺序不是固定的
    注意:要想锁住资源必须保证大家拿到的是同一把锁

    怎么使用?
    在需要加锁的地方 lock.acquire()表示锁定 ,在代码执行完后 一定要lock.release()

    加锁举例:
    from multiprocessing import Process,Lock
    import time
    #买了把锁
    mutex = Lock()
    def task1(Lock):
    Lock.acquire()
    time.sleep(3)
    print("===>")
    Lock.release()
    def task2(Lock):
    Lock.acquire()
    print("=======>")
    Lock.release()
    def task3(Lock):
    Lock.acquire()
    print("===============>")
    Lock.release()
    if __name__ == '__main__':
    p1 = Process(target=task1,args=(mutex,))
    p2 = Process(target=task2,args=(mutex,))
    p3 = Process(target=task3,args=(mutex,))
    p1.start()
    p3.start()
    p2.start()
    print("over")
    #加锁后开启进程顺序就变成了 执行进程顺序(串性)



    例子:抢票
    from multiprocessing import Process,Lock
    import json
    import time,random
    #买了把锁
    def task1(name):
    time.sleep(random.randint(1,3))
    with open("D:py_yingyong新课上练习ppppp.json","rt",encoding="utf-8")as f:
    dic=json.load(f)
    print("%s进行了查票 余票%s张"%(name,dic["count"]))
    return dic
    def task2(name):
    time.sleep(random.randint(1,3))
    with open("D:py_yingyong新课上练习ppppp.json","rt",encoding="utf-8")as f:
    dic=json.load(f)
    print("%s进行了购票操作 现余票%s张"%(name,dic["count"]))
    if dic["count"]>0:
    dic["count"]=dic["count"] - 1
    with open("D:py_yingyong新课上练习ppppp.json", "wt", encoding="utf-8")as f:
    json.dump(dic,f)
    print("%s购票成功"%name)
    return
    def task3(Lock,name):
    task1(name)
    Lock.acquire()
    task2(name)
    Lock.release()
    if __name__ == '__main__':
    mutex = Lock()
    for i in range(5):
    p1 = Process(target=task3,args=(mutex,"客户%s"%i))
    p1.start()

    3.IPC
    指的是进程间的通讯
    之所以开启子进程 肯定是需要他来帮我们完成任务 很多情况下,需要将数据返回给父进程
    然而 进程内存是物理隔离的
    解决方案:
    1.将共享数据放到文件中
    2.管道 subprocess中的那个 管道只能单项通讯 必须存在父子关系
    3.共享一个内存区域 需要操作系统帮你分配 速度快:
    Manager 共享列表或字典
    from multiprocessing import Process, Manager
    import time
    def task(li,i):
    print("子进程xxxx")
    li[0]=1+i
    print(li[0])
    # dic["name"]="xx"
    if __name__ == '__main__':
    # with Manager() as m:
    m=Manager()
    li=m.list([2])
    # dic=m.dict({})
    # li=[1]
    #开启子进程
    for i in range(3):
    p=Process(target=task,args=(li,i))
    p.start()
    p.join(1)
    print(li)


    Queue 是一个队列 带有阻塞效果:
    from multiprocessing import Process,Queue
    #创建队列
    q=Queue()#阻塞
    q.put("len")
    q.put(124)
    q.put("kkkk")
    print(q.get())
    #如果取空会等待
    print(q.get())


    q=Queue(3)#阻塞 先进先出
    q.put("len",block=False)
    #当容量满的时候在执行put会默认阻塞知道执行了get为止
    #如果修改block=False 直接报错 因为没有地方放了
    q.put(124,block=False)
    q.put("kkkk",block=False)
    #去除数据 如果没有数据默认是阻塞的 直到执行了put
    #如果取空会等待
    print(q.get(),block=False)
    #如果修改block=False 直接报错 因为没有数据可以取了
    print(q.get(),block=False)
    print(q.get())
    print(q.get())

    q=Queue()
    #如果满了 愿意等待3秒 如果还等不到位置 就会报错
    q.put("len",timeout=3)
    q.put(124,timeout=3)
    q.put("kkkk",timeout=3)


    print(q.get(),timeout=3)
    #如果数据空了 愿意等待3秒 如果还没有数据 就会报错
    print(q.get(),timeout=3)
    print(q.get(),timeout=3)
    print(q.get(),timeout=3)
  • 相关阅读:
    【JAVA与C#比较】其它
    C#和java之间的一些差异与共性
    C#与Java的语法差异
    关于npm本地安装模块包(node_modules),安装不了的问题
    vue
    vue
    vue
    vue
    v
    vue -model
  • 原文地址:https://www.cnblogs.com/yanhui1995/p/9931232.html
Copyright © 2020-2023  润新知