多进程
- 启用多进程,可以解决python调用计算机CPU多核运算的问题
启动一个进程
import multiprocessing
import time
def run(name):
time.sleep(2)
print('hello',name)
for i in range(10):
p = multiprocessing.Process(target=run,args=('man %s'%i,))
p.start()
from multiprocessing import Process
import os
def info(title):
print(title)
print('module name:', __name__)
print('parent process:', os.getppid())#父进程ID
print('process id:', os.getpid())#当前进程ID
print("
")
def f(name):
info(' 33[31;1mfunction f 33[0m')#子进程的info,子进程的PPID=主进程的PID
print('hello', name)
if __name__ == '__main__':
info(' 33[32;1mmain process line 33[0m')#主进程的info
#在window,主进程的PPID=pycharm的PID
p = Process(target=f, args=('bob',))
p.start()
p.join()
- 每一个进程都是由一个父进程启动的
进程间数据交互
- 不管哪种方式,都是找一个中间代理,相当于不同国家的人交流需要找一个翻译
- 不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:
进程间数据交互(通信)的方式
1.Queues
- 使用方法跟threading里的queue差不多。这里的queue不是线程中的,线程中的queue只能在创建线程的主进程之间由它的线程使用
from multiprocessing import Process, Queue
#用法和线程的queue是一样的,但这里引入的是进程的queue
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()
2.Pipes管道
- 管道实例化后会产生两个通道,分别交给两个进程
- 通过send和recv来交互数据,这是一个双向的管道,child和parent可以互相收发
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello'])
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, 'hello']"
p.join()
3.Managers经理/代理
- 以代理的方式在进程间共享字典或列表形式的数据
from multiprocessing import Process, Manager
import os
def f(d, l):
d[1] = '1'
d['2'] = 2
d[0.25] = None
l.append(os.getpid())
print(l)
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()#生成一个字典,在多个进程间共享和传递
l = manager.list(range(5))#生成一个列表含5个初始值,在多个进程间传递和共享
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l))
p.start()
p_list.append(p)
for res in p_list:
res.join()
print(d)
print(l)
进程同步LOCK
- 进程不能操作同一块数据,那么进程锁的意义是什么?
- 进程锁存在的意义是保证各进程在屏幕输出时不会乱
比如:进程1,打印hello word 1,进程2打印hello word 2,没有锁,进程1的打印还没结束,进程2进来了,就可能造成混乱。(window上不会发生,linux上测试,2.7以下python)
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
try:
print('hello world', i)
finally:
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
进程池
- 进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
- 进程池中有两个方法:
- apply同步执行-串行
- apply_async异步执行-并行
from multiprocessing import Process, Pool
import time,os
def Foo(i):
time.sleep(2)
print('in process',os.getpid())
return i + 100
def Bar(arg):
print('-->exec done:', arg)
if __name__ == '__main__':
pool = Pool(5)#同时允许5个进程进入进程池,其他进程挂起
for i in range(10):
pool.apply_async(func=Foo, args=(i,), callback=Bar)#callback回调函数
# pool.apply(func=Foo, args=(i,))
print('end')
pool.close()#这里join一定是在close之后,且必须要加join,否则主进程不等待创建的子进程执行完毕
pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。