zoukankan      html  css  js  c++  java
  • 2018.11.8

    1守护进程

    from multiprocessing import Process
    import time

    def task():
    print("妃子 升级为皇后")
    time.sleep(3)
    print("皇后 挂了")

    if __name__ == '__main__':
    p = Process(target=task)
    # 将这个子进程设置为当前进程守护进程
    p.daemon = True
    p.start()
    print("崇祯登基")
    print("崇祯驾崩了....")


    # 守护进程的代码非常简单
    """
    p.daemon = True
    就是主程序结束了 子进程就马上结束(子进程代码就不会执行或中断执行)
    注意必须在启动进程之前执行
    什么时候需要使用守护进程
    例如: qq中有个下载视频 应该用子进程去做 但是 下载的过程中 qq退出 那么下载也没必要继续了
    使用场景不多 了解即可


    2.互斥锁 ******
    from multiprocessing import Process, Lock


    def task1(lock):
    lock.acquire()
    for i in range(10000):
    print("11111")
    lock.release()


    def task2(lock):
    lock.acquire()
    for i in range(10000):
    print("22222")
    lock.release()


    def task3(lock):
    lock.acquire()
    for i in range(10000):
    print("33333")
    lock.release()


    if __name__ == '__main__':
    res = Lock()
    p1 = Process(target=task1, args=(res,))
    p2 = Process(target=task2, args=(res,))
    p3 = Process(target=task3, args=(res,))
    p1.start()
    p2.start()
    p3.start()
    # p1.start()
    # p1.join()
    # p2.start()
    # p2.join()
    # p3.start()
    # p3.join()
    # 什么时候用锁?
    # 当多个进程 同时读写同一份数据 数据很可能就被搞坏了
    # 第一个进程写了一个中文字符的一个字节 cpu被切到另一个进程
    # 另一个进程也写了一个中文字符的一个字节
    # 最后文件解码失败
    # 问题之所以出现 是因为并发 无法控住顺序
    # 目前可以使用join来将所有进程并发改为串行

    # 与join的区别?
    # 多个进程并发的访问了同一个资源 将导致资源竞争(同时读取不会产生问题 同时修改才会出问题)
    # 第一个方案 加上join 但是这样就导致了 不公平 相当于 上厕所得按照颜值来
    # 第二个方案 加锁 谁先抢到资源谁先处理[
    # 相同点: 都变成了串行
    # 不同点:
    # 1.join顺序固定 锁顺序不固定!
    # 2.join使整个进程的任务全部串行 而锁可以指定哪些代码要串行

    # 锁使是什么?
    # 锁本质上就是一个bool类型的标识符 大家(多个进程) 在执行任务之前先判断标识符
    # 互斥锁 两个进程相互排斥

    # 注意 要想锁住资源必须保证 大家拿到锁是同一把

    # 怎么使用?
    # 在需要加锁的地方 lock.acquire() 表示锁定
    # 在代码执行完后 一定要lock.release() 表示释放锁
    # lock.acquire()
    # 放需要竞争资源的代码 (同时写入数据)
    # lock.release()

    3模拟抢票软件 自己要在json文件里写个count
    """
    抢票!
    多个用户在同时读写同一个数据

    """

    from multiprocessing import Process,Lock
    import json,time,random

    # 查看余票
    def show_ticket(name):
    time.sleep(random.randint(1,3))
    with open(r"ticket.json","rt",encoding="utf-8") as f:
    dic = json.load(f)
    print("%s查看 剩余票数:%s" % (name ,dic["count"]))

    # 购买票
    def buy_ticket(name):
    # 购买前再次查询
    with open(r"ticket.json", "rt", encoding="utf-8") as f:
    # 修改数据
    dic = json.load(f)
    if dic["count"] > 0:
    dic["count"] -= 1
    # 模拟网络延迟
    time.sleep(random.randint(1,3))
    # 模拟服务器收到数据 写入文件
    with open(r"ticket.json", "wt", encoding="utf-8") as f2:
    json.dump(dic,f2)
    print("%s 购票成功!" % name)

    def task(lock,name):
    # 查看余票可以并发执行 不需要锁住
    show_ticket(name)
    # 购票的操作需要锁 因为设涉及到同时修改数据
    lock.acquire()
    buy_ticket(name)
    lock.release()

    if __name__ == '__main__':

    # 买个锁
    mutex = Lock()
    for i in range(11):
    p = Process(target=task,args=(mutex,"客户%s" % i))
    p.start()

    # 查询票这个事情 可以多个进程同时执行
    # 但是买票这个过程 不能同时进行 前一个没买完 后一个就不能买

    """
    IPC 指的是进程间通讯
    之所以开启子进程 肯定需要它帮我们完成任务 很多情况下 需要将数据返回给父进程
    然而 进程内存是物理隔离的
    解决方案:
    1.将共享数据放到文件中 就是慢
    2.管道 subprocess中的那个 管道只能单向通讯 必须存在父子关系
    3.共享一块内存区域 得操作系统帮你分配 速度快

    """
    4from multiprocessing import Process,Manager
    import time

    def task(dic):
    print("子进程xxxxx")
    # li[0] = 1
    # print(li[0])
    dic["name"] = "xx"

    if __name__ == '__main__':
    m = Manager()
    # li = m.list([100])
    dic = m.dict({})
    # 开启子进程

    """
    5 进程间通讯的另一种方式 使用queue
    queue 队列
    队列的特点:
    先进的先出
    后进后出
    就像扶梯
    """
    from multiprocessing import Process,Queue


    # 基础操作 必须要掌握的
    # 创建一个队列
    # q = Queue()
    # # 存入数据
    # q.put("hello")
    # q.put(["1","2","3"])
    # q.put(1)
    # # 取出数据
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get())

    # 阻塞操作 必须掌握
    # q = Queue(3)
    # # # 存入数据
    # q.put("hello",block=False)
    # q.put(["1","2","3"],block=False)
    # q.put(1,block=False)
    # # 当容量满的时候 再执行put 默认会阻塞直到执行力了get为止
    # # 如果修改block=False 直接报错 因为没地方放了
    # # q.put({},block=False)
    #
    # # # # 取出数据
    # print(q.get(block=False))
    # print(q.get(block=False))
    # print(q.get(block=False))
    # # 对于get 当队列中中没有数据时默认是阻塞的 直达执行了put
    # # 如果修改block=False 直接报错 因为没数据可取了
    # print(q.get(block=False))

    # 了解
    q = Queue(3)
    q.put("q",timeout=3)
    q.put("q2",timeout=3)
    q.put("q3",timeout=3)
    # 如果满了 愿意等3秒 如果3秒后还存不进去 就炸
    # q.put("q4",timeout=3)

    print(q.get(timeout=3))
    print(q.get(timeout=3))
    print(q.get(timeout=3))
    # 如果没了 愿意等3秒 如果3秒后还取不到数据 就炸
    print(q.get(timeout=3))

  • 相关阅读:
    Java核心技术 卷一 笔记四 库类的直接使用
    Java核心技术 卷一 笔记三 大数值及数组
    Java核心技术 卷一 笔记2 字符串的复制
    Java核心技术 卷一 笔记1
    修改css 样式后, hover事件 不生效
    修改 element ui input 输入框 样式不生效问题
    css3 计算属性
    Vue3 改动系列
    浏览器实现,向下滑动 鼠标滚轮,页面横向移动
    linux ceont0s7 vue 打包压缩图片 一直报错
  • 原文地址:https://www.cnblogs.com/jutao/p/9932147.html
Copyright © 2011-2022 走看看