• 进程同步


    进程同步工具
    有先后顺序 就是同步
    进程之间 就是一部
    希望原本一部的多进程操作,维持一个顺序


    lock = Lock() ## 创造了一把锁
    lock.acquire() ##获取了这把锁的钥匙
    lock.release() ## 归还这把锁的钥匙
    当几个人进一间屋子,如果第一个人获取了锁的钥匙,那他进去后会带着钥匙进去 然后反锁,后面的人进不去
    只有他把锁还了以后 下一个人才可以拿锁进去

    当多个进程共享一段数据的时候,数据会出现不安全的现象,这就需要枷锁来维护数据的安全性
    拿抢票的例子来说:
    import json
    import time
    from multiprocessing import Lock
    from multiprocessing import Process

    def search(i):
    with open('dp','r') as f:
    count_dic = json.load(f)
    time.sleep(0.2)
    print('person %s 余票 : %s张'%(i,count_dic['count']))

    def buy(i):
    with open('dp','r') as f:
    count_dic = json.load(f)
    time.sleep(0.2)
    if count_dic['count'] >0:
    count_dic['count'] -=1
    print('person %s 购票成功' %i)
    time.sleep(0.2)
    with open('dp','w') as f:
    json.dump(count_dic,f)

    def task(i,lock):
    search(i)
    lock.acquire() ##如果之前已经被acquire了 且 没有被release name进程会在这里阻塞
    buy(i)
    lock.release()

    if __name__ =='__main__':
    lock = Lock()
    for i in range(10):
    p = Process(target=task,args=(i,lock))
    p.start()

    信号量
    from multiprocessing import Semaphore ##信号量
    信号量的本质
    多把钥匙对应一把锁
    lock+count计数
    拿ktv举个例子,有10个人 但是只有4个小房子 这样子怎么办呢?

    import time
    import random
    from multiprocessing import Process,Semaphore
    def ktv(i,sem):
    sem.acquire()
    print('person %s 进入了ktv' %i)
    time.sleep(random.randint(1,4))
    print('person %s 走出了ktv' %i )
    sem.release()

    if __name__ == '__main__':
    sem = Semaphore(4)
    for i in range(10):
    p = Process(target=ktv,args=(i,sem))
    p.start()

    #事件
    from multiprocessing import Event,Process

    # wait() 方法 等待
    # 阻塞 如果这个标志是False 那么就阻塞
    # 非阻塞 如果这个标志是True 那么就非阻塞
    # 查看标志 is_set()
    # 修改标志 set() 将标志设置为True
    # clear() 将标志设置为False

    e = Event()
    print(e.is_set()) ##在事件的创建之初, 默认是False
    e.set() ##将标志设置为True
    print(e.is_set())
    e.wait() ## 相当于什么都没做 pass
    e.clear() ##将标志设置为False
    e.wait() ##永远阻塞
    e.wait(timeout = 10) ##如果信号在阻塞10s之内变为True,那么不继续阻塞直接pass
    ##如果就阻塞10s之后状态还是没变,那么继续
    print(e.is_set()) ##无论前面的wait的timeout是否通过,我的状态都不会因此改变

    #红绿灯模型
    #控制交通灯的进程
    import time
    import random
    def traffic_light(e):
    print('33[1;31m 红灯亮33[0m')
    while True:
    time.sleep(2)
    if e.is_set():
    print('33[1;31m 红灯亮33[0m')
    e.clear()
    else:
    print('33[1;32m 绿灯亮33[0m')
    e.set()

    ##车 等或者通过
    def car(id,e):
    if not e.is_set():
    print('car %s 等待' % id)
    e.wait()
    print('car %s 通过' %id)

    def police_car(id,e):
    if not e.is_set():
    e.wait(timeout=0.5)
    print('police car %s 通过' %id)

    ##主进程 启动交通控制灯 启动车的进程
    if __name__ == '__main__':
    e = Event()
    p = Process(target=traffic_light,args=(e,))
    p.start()
    car_lst = [car,police_car]
    for i in range(20):
    p = Process(target=random.choice(car_lst),args=(i,e))
    p.start()
    time.sleep(random.randrange(0,3,2))



    总结
    进城之间的数据是隔离的
    进程御锦城之间是不能自由的交换内存数据的
    全局的变量在子进程中修改 其他进程是感知不到的
    守护进程
    特点 生命周期只和主进程的代码有关系,和其他子进程没关系
    用处 报活
    多进程启动tcp协议的socket来完成并发
    进程的同步控制---进程之间有一些简单的信号传递,但是用户不能感知,且用户不能传递自己想传递的内容

    信号量
    锁+计数器实现
    事件 wait
  • 相关阅读:
    Thinkphp5+PHPExcel实现批量上传表格数据
    使用ECharts画K线图
    ThinkPHP5+Layui实现图片上传加预览
    SVN使用教程总结
    JS内置对象方法
    头像上传【实用php】
    Sublime Text 3 快捷键总结
    javascript--基础 三元表达式
    javascript---运算符、表达式、递增、比较运算符、逻辑运算符
    导入dmp的sql语句
  • 原文地址:https://www.cnblogs.com/liuafan/p/9367967.html
Copyright © 2020-2023  润新知