Python学习——多进程学习

基本的多进程的使用:

 1 from multiprocessing import Process
 2 import threading
 3 import os
 4 
 5 
 6 def info(title):
 7     print(title)
 8     print('module name:', __name__)
 9     print('parent process:', os.getppid())
10     print('process id:', os.getpid())
11     print("

")
12 
13 
14 def f(name):
15     info('33[31;1mfunction f33[0m')
16     print('hello', name)
17 
18 
19 if __name__ == '__main__':
20     info('33[32;1mmain process line33[0m')
21     #p = threading.Thread(target=f, args=('bob',))
22     p = Process(target=f, args=('bob',))    #its parent process will be this program ,not pycharm.
23     p.start()
24     p.join()

不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:

Queue

from multiprocessing import Queue

pickle(序列化,实际是把内存的数据放到硬盘上,所以不同的进程可以都可以访问,当然整个过程进行了包装)

 1 from multiprocessing import Process, Queue
 2 import queue
 3 
 4 def f(q):
 5     q.put([42, None, 'hello'])
 6 
 7 
 8 if __name__ == '__main__':
 9     q = Queue()   #不出现报错的原因在于,pickle模块实现了对数据的封装(复制一个q进入另一个进程,还有其他后续处理)
10     #q = queue.Queue()  #会出现报错,因为两个进程之间不同互通数据。
11     p = Process(target=f, args=(q,))
12     p.start()
13     print(q.get())  # prints "[42, None, 'hello']"
14     p.join()

Manager

这个是实时共享数据的。

 1 from multiprocessing import Process, Manager
 2 import os
 3 
 4 def f(d, l):
 5     d[1] = os.getpid()  #可以利用这个看出来,这个数据是共享的数据
 6     d['2'] = 2
 7     print(d)
 8     d[0.25] = None
 9     l.append(os.getpid())
10 
11     print(l)
12 
13 if __name__ == '__main__':
14     with Manager() as manager:  #Manager可以建立多种进程共享数据
15         d = manager.dict()   #生成字典,可在多个进程间共享和传递
16         l = manager.list(range(5))   #生成一个列表,里面预置了0-4,5个值,可在多个进程间共享和传递
17         p_list = [] #主要给下面进行等待所以进程结束的
18         for i in range(10):
19             p = Process(target=f, args=(d, l))
20             p.start()
21             p_list.append(p)
22         for res in p_list:
23             res.join()
24 
25         print(d)
26         print(l)

Lock

多线程的Lock,是为了避免屏幕输出或者其他共用输出出现混乱编码的情况。

但是多进程如果是使用manager来做这个管理就会自动加锁,所以不需要自己管理。

进程池

类似于现场的信号量。

必须注意要先close(),再进行join()

pool.close()
pool.join()

进程池中有两个方法:

  • apply
  • apply_async  

使用方法:

#pool.apply_async(func=Foo, args=(i,), callback=Bar)   #这个是异步执行,就是并行;callback,回调,就是执行完Foo后,再执行Bar,
#pool.apply(func=Foo, args=(i,)) #这个是同步执行,就是串行

callback:是利用父进程来进行调用,这样可以提高效率,比如执行完进程之后,连接数据库修改日志的时候;

 1 from  multiprocessing import Process, Pool,freeze_support
 2 import time
 3 import os
 4 
 5 def Foo(i):
 6     time.sleep(2)
 7     print("in process",os.getpid())
 8     return i + 100
 9 
10 def Bar(arg):
11     print('-->exec done:', arg,os.getpid())
12 
13 if __name__ == '__main__':
14     #freeze_support()
15     pool = Pool(processes=5) #允许进程池同时放入5个进程
16     print("主进程",os.getpid())
17     for i in range(10):
18         pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback=回调
19         #pool.apply(func=Foo, args=(i,)) #串行
20         #pool.apply_async(func=Foo, args=(i,)) #串行
21     print('end')
22     pool.close()
23     pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。.join()
原文地址:https://www.cnblogs.com/Ian-learning/p/8626728.html