python 进程池的使用

进程同步

进程的数据是独立存在的,进程也能加锁。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

 进程为何要加锁?app

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

进程池

 

apply  同步执行 串行async

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()

 

 运行结果ui

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

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

 

并行化blog

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

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

相关文章
相关标签/搜索