zoukankan      html  css  js  c++  java
  • python 进程池的使用

    进程同步

    进程的数据是独立存在的,进程也能加锁。

    from multiprocessing import Process, Lock
    
    def f(l,i):
        l.acquire()
        print('hello world',i)
        l.release()
    
    
    if __name__ =='__main__':
        lock = Lock()   #获得锁的实例
        for i in range(10):
            Process(target=f,args=(lock,i)).start() #启动进程,并且把锁的实例传到进程
    

     运行结果

    hello world 0
    hello world 2
    hello world 1
    hello world 3
    hello world 6
    hello world 7
    hello world 8
    hello world 4
    hello world 5
    hello world 9
    

     进程为什么要加锁?

    因为进程的数据是独立存在的,并不会共享同一块数据。但是有些资源是共享的,比如显示器。如果每个进程都要输出内容,那么显示的就很乱了,这个锁就是在某个进程独自输出的时候独占,不会被其它进程干扰。

    进程池

    apply  同步执行 串行

    apply_async  异步执行 并行

    from multiprocessing import Process, Pool,freeze_support
    import time
    import os
    
    def Foo(i):
        time.sleep(2)
        print('当前进程',os.getpid())
        return i + 100
    
    def Bar(arg):
        print("-->exec done:",arg)
    
    if __name__ =='__main__':
        freeze_support()
        pool = Pool(processes=5) #允许进程池中同时放入5个进程
    
        for i in range(10):
            #pool.apply_async(func=Foo,args=(i,),callback=Bar)
            pool.apply(func=Foo,args=(i,))
    
        print('end')
        pool.close()
        pool.join() #进程池中进程执行完毕后在关闭,如果注释,那么程序直接关闭。.join()
    

     运行结果

    当前进程 5816  #sleep 2s  打印
    当前进程 8124  #sleep 2s  打印
    当前进程 6488  #sleep 2s  打印
    当前进程 5356
    当前进程 7036
    当前进程 5816
    当前进程 8124
    当前进程 6488
    当前进程 5356
    当前进程 7036
    end
    

     以上是同步执行,程序显示的效果是串行化执行。

    并行化

    from multiprocessing import Process, Pool,freeze_support
    import time
    import os
    
    def Foo(i):
        time.sleep(2)
        print('当前进程',os.getpid())
        return i + 100
    
    def Bar(arg):
        print("-->exec done:",arg)
    
    if __name__ =='__main__':
        freeze_support()
        pool = Pool(processes=5) #允许进程池中同时放入5个进程
    
        for i in range(10):
            pool.apply_async(func=Foo,args=(i,),callback=Bar)
            #pool.apply(func=Foo,args=(i,))
    
        print('end')
        pool.close()
        pool.join() #进程池中进程执行完毕后在关闭,如果注释,那么程序直接关闭。.join()
    

     运行结果

    end
    当前进程 6060  #一次打印5个
    当前进程 6952
    -->exec done: 100
    -->exec done: 101
    当前进程 3388
    -->exec done: 102
    当前进程 1600
    -->exec done: 103
    当前进程 7648
    -->exec done: 104
    当前进程 6060
    当前进程 6952
    -->exec done: 105
    -->exec done: 106
    当前进程 3388
    -->exec done: 107
    当前进程 1600
    -->exec done: 108
    当前进程 7648
    -->exec done: 109
    

    callback() 回调函数,子进程执行完func,之后在调用的函数。 那么这个函数是子进程调用的还是主进程调用的?

    from multiprocessing import Process, Pool,freeze_support
    import time
    import os
    
    def Foo(i):
        time.sleep(2)
        print('当前进程',os.getpid())
        return i + 100
    
    def Bar(arg):
        print("-->exec done:",arg,os.getpid())  #显示调用当前函数的进程id
    
    if __name__ =='__main__':
        freeze_support()
        pool = Pool(processes=5) #允许进程池中同时放入5个进程
        print("主进程",os.getpid())  #显示主进程id
        for i in range(10):
            pool.apply_async(func=Foo,args=(i,),callback=Bar)
            #pool.apply(func=Foo,args=(i,))
    
        print('end')
        pool.close()
        pool.join() #进程池中进程执行完毕后在关闭,如果注释,那么程序直接关闭。.join()
    

     运行结果

    主进程 7052
    end
    当前进程 7992
    当前进程 1848
    -->exec done: 101 7052
    -->exec done: 100 7052
    当前进程 2212
    -->exec done: 102 7052
    当前进程 980
    当前进程 8064
    -->exec done: 103 7052
    -->exec done: 104 7052
    当前进程 7992
    -->exec done: 105 7052
    当前进程 1848
    -->exec done: 106 7052
    当前进程 2212
    -->exec done: 107 7052
    当前进程 8064
    当前进程 980
    -->exec done: 109 7052
    -->exec done: 108 7052
    

     这里可以看到是主进程调用的回调,这些写的优点是,比如子进程做了数据备份要写到数据库,如果每个子进程都在执行的函数里面写,那么每个进程都要连接一次数据库,用主进程调用的方式就是可以省去这么多的连接数据库的操作。效率更高。

  • 相关阅读:
    用脚本实现对pm2.5 数据的获取
    虚拟机下的快盘空间分配方案
    C++中new的用法
    只在堆或栈上生成对象
    Virtualbox识别USB设备
    最长公共字序列
    gdb 打印vector 等stl数据
    LC_CTYPE: cannot change locale
    字符串压缩
    对象的概念
  • 原文地址:https://www.cnblogs.com/qing-chen/p/7690575.html
Copyright © 2011-2022 走看看