zoukankan      html  css  js  c++  java
  • 多进程相关内容(IPC)

    多进程相关内容

    1.守护进程(daemon)

    ​ 主进程创建守护进程: 1.守护进程会在主进程代码执行结束后就终止

    ​ 2.守护进程内无法再开启子进程,否则抛出异常

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

    from multiprocessing import Process
    
    def task():
        print('son is running')
    
        print('son is done')
    
    if __name__ == '__main__':
        p = Process(target = task)
        p.daemon = True		#要在p.start()前设置,设置p为守护进程
        p.start()
    
        print('father process')
    

    2.进程同步

    ​ 由于多道技术要求物理层面进程之间内存相互隔离,即数据不能共享.但是我们能共享同一套文件系统,所以访问同一个文件或同一个打印终端是没有任何问题的.

    ​ 由于创建进程的速度不一,导致在共享文件就会产生数据错乱或打印错乱,我们引入了lock的概念,加锁:将并发变成串行,牺牲了运行效率,但避免了对硬件资源的竞争和保证了数据安全.

    1.加锁

    #模拟抢票
    #json中存放字典的key格式必须以双引号注明
    from multiprocessing import Process,Lock
    import json
    
    #查询余票信息
    def search():
        with open('db.json') as f:
            data = json.load(f)
            print('剩余票数:',data['count'])
    
    #购买
    def buy():
    
        #由于网络延时,需重新获取余票信息
        with open('db.json') as f:
            data = json.load(f)
    
            if data['count']>0:
                data['count'] -= 1
                with open('db.json','wt') as fw:
                    json.dump(data,fw)
                    print('抢票成功')
    
    def task(mutex):
        search()
        
        mutex.acquire() #加锁
        buy()
        mutex.release() #解锁
        
    if __name__ == '__main__':
        mutex = Lock()  #创建锁
        
        for i in range(5):
            p = Process(target=task,args=(mutex,))
            p.start()
    
    #加锁:保证多个进程修改同一块数据,同一时间只能有一个任务可以进行修改即串行的修改
    #适用于:	1.共享数据较大,效率低
    #		  2.需要人为加锁
    
    

    3.基于multiprocessing模块的IPC通信机制(推荐使用)

    ​ IPC:interface_process_communication(进程间通信),multiprocessing模块支持两种形式:队列和管道,这两种方式都是用来.

    manager的使用

    from multiprocessing import Process,Manager,Lock
    
    
    def task(data,lock):
        lock.acquire()
        num = data[0]
        data[0] = num - 1
        lock.release()
    
        print('son is done')
    
    
    if __name__ == '__main__':
        ls = [100]
        m = Manager()           #创建管理器
        syncls = m.list(ls)     #同步列表
    
        lock = Lock()
    
        ps = []
        for i in range(10):
            p = Process(target=task,args=(syncls,lock))
            p.start()
            ps.append(p)
    
        for p in ps:p.join()
    
        print(ls)       #100
        print(syncls)   #90
    

    ​ 队列和管道都是将数据存放于内存中的(即在运行时在内存中开辟一块共同存放数据的区域)

    #队列原则:先进先出
    from multiprocessing import Queue
    
    q = Queue(5)    #创建队列中,同时只能存在最多元素maxsize=5
    q.put(1)        #放入元素
    q.put(1,block=True,timeout=1) #block阻塞,默认为true,timeout延时(当队列为空时,在该时间内放入元素
    
    print(q.get(1) )   #取出队列元素
    
    
    #栈,函数调用,原则:后进先出
    def a():
        b()
    
    
    def b():
        c()
    
    
    def c():
        print('c')
        raise  Exception
    
    
    a()
    
  • 相关阅读:
    Delphi实现文件关联
    用Delphi实现文件关联
    Delphi 7使用自定义图标关联文件类型
    redux-form的学习笔记
    妙用 `package.json` 快速 `import` 文件(夹)
    【webpack2】-- 入门与解析
    黑科技:CSS定制多行省略
    DOM操作和样式操作库的封装
    webstorm 2016 激活破解
    js/jq仿window文件夹框选操作插件
  • 原文地址:https://www.cnblogs.com/bruce123/p/11184402.html
Copyright © 2011-2022 走看看