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

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

原文地址:https://www.cnblogs.com/qing-chen/p/7690575.html