zoukankan      html  css  js  c++  java
  • python 多进程

    multiprocessing 模块介绍

    python中的多线程无法利用多核优势,如果想要充分的使用多核cpu的资源,os.cpu_count可以查看逻辑cpu数,在python中大部分情况需要使用多进程,python提供了multiprocessing

    muliprocessing模块用来开启子进程,并在子进程中执行我们制定的任务(比如函数),这个模块与多

    线程模块threading编程接口类似

    multiprocessing模块的功能众多,支持子进程,通信和共享数据,执行不同形式的同步,提供了Process,Queue,Pipe,Lock等组件

    multiprocessing与线程不同的是进程没有任何共享状态,进程修改数据仅限于该进程内

    Process类

    Process(group,target=func,name=str,args(x,),kwargs={'num':1,})

    由该类实例化得到的对象,表示一个子进程中的任务

    强调:需要使用关键字的方式来给Process传参数

      args指定的为target对应的函数传位置参数,是元组形式,括号类必须有逗号

    参数介绍:

    1 group参数未使用,值始终为None
    2 
    3 target表示调用对象,即子进程要执行的任务
    4 
    5 args表示调用对象的位置参数元组,args=(1,2,'egon',)
    6 
    7 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
    8 
    9 name为子进程的名称


    方法介绍:

    1.P.start()启动进程,并调用该子进程中的P.run()
    2.P.run()进程启动时运行的方法,他去调用target指定的函数,我们在自定义/继承与Process的类总一定要实现run()这个方法
    3.P.terminate()强制终止进程p,不会进行任何清理操作,如果p创建了子进程,那么这个子进程就成了僵尸进程
      使用该方法需要特别小心这种情况,如果p还保存了一个锁那么也将不会被释放,进而导致死锁
    4.P.is_alive()如果p任然在运行,那么返回True
    5.P.join([timeout])主线程序等待p终止(强调,是主线程序处于等待状态,p处于运行状态),timeout是可选的
      超时时间,P.join()只能join住start开启的进程,放在start()下边,而不能join住run开启的进程

    属性介绍:

    p.deamon,默认值为False,如果设为True,代表p为后台运行的守护进程,当p父进程终止时,p也随之终止,并且
    设定为True后,p不能创建自己的新进程,p.deamon必须在p.start()之前设置

    p.name进程的名称

    p.pid进程的id


    process类的使用

    在windo中process()必须放到if__name__=='__main__':下去运行,不会在导入时被调用

    由于window没有fork,多处理模块启动一个新的python进程并导入调用模块
    如果在导入时调用process(),name这将启动无限继承的新进程(或直到机器耗尽资源)

    创建并开启子进程的两种方式

    #开进程的方法一:
    import time
    import random
    from multiprocessing import Process
    def piao(name):
    print('%s piaoing' %name)
    time.sleep(random.randrange(1,5))
    print('%s piao end' %name)

    p1=Process(target=piao,args=('egon',)) #必须加,号
    p2=Process(target=piao,args=('alex',))
    p3=Process(target=piao,args=('wupeqi',))
    p4=Process(target=piao,args=('yuanhao',))

    p1.start()
    p2.start()
    p3.start()
    p4.start()
    print('主线程')

    方法一

    
    

    #开进程的方法二:
    import time
    import random
    from multiprocessing import Process


    class Piao(Process):
    def __init__(self,name):
    super().__init__()
    self.name=name
    def run(self):
    print('%s piaoing' %self.name)

    time.sleep(random.randrange(1,5))
    print('%s piao end' %self.name)

    p1=Piao('egon')
    p2=Piao('alex')
    p3=Piao('wupeiqi')
    p4=Piao('yuanhao')

    p1.start() #start会自动调用run
    p2.start()
    p3.start()
    p4.start()
    print('主线程')

    方法二

    进程直接的内存空间是隔离的

    守护进程

    主进程创建守护进程

      其一:守护进程会在主进程代码执行结束后就终止

      其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

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

    from multiprocessing import Process
    import time
    import random

    class Piao(Process):
    def __init__(self,name):
    self.name=name
    super().__init__()
    def run(self):
    print('%s is piaoing' %self.name)
    time.sleep(random.randrange(1,3))
    print('%s is piao end' %self.name)


    p=Piao('egon')
    p.daemon=True #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行
    p.start()
    print('主')

    进程同步(锁)

    进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,

    而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理

    #文件db的内容为:{"count":1}
    #注意一定要用双引号,不然json无法识别
    from multiprocessing import Process,Lock
    import time,json,random
    def search():
    dic=json.load(open('db.txt'))
    print('33[43m剩余票数%s33[0m' %dic['count'])

    def get():
    dic=json.load(open('db.txt'))
    time.sleep(0.1) #模拟读数据的网络延迟
    if dic['count'] >0:
    dic['count']-=1
    time.sleep(0.2) #模拟写数据的网络延迟
    json.dump(dic,open('db.txt','w'))
    print('33[43m购票成功33[0m')

    def task(lock):
    search()
    lock.acquire()
    get()
    lock.release()
    if __name__ == '__main__':
    lock=Lock()
    for i in range(100): #模拟并发100个客户端抢票
    p=Process(target=task,args=(lock,))
    p.start()

    加锁:购票行为由并发变成了串行,牺牲了运行效率,但保证了数据安全

    #加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。
    虽然可以用文件共享数据实现进程间通信,但问题是:
    1.效率低(共享数据基于文件,而文件是硬盘上的数据)
    2.需要自己加锁处理
  • 相关阅读:
    基于fis3的组件可视化道路
    前端性能——监控起步
    uploadify使用的一些经验总结
    浏览器加载和渲染HTML的过程(标准定义的过程以及现代浏览器的优化)
    github常见问题【转自百度知道】
    轮播的实现方式
    前端打包构建工具grunt快速入门(大篇幅完整版)
    一些很棒的js代码
    如何高效的编写Verlog HDL——菜鸟版
    基于FPGA的肤色识别算法实现
  • 原文地址:https://www.cnblogs.com/fushaunglin/p/9594532.html
Copyright © 2011-2022 走看看