Python学习笔记Day10 - 多进程
目录
1. 多进程multiprocessing
io 操作不占用cpu,计算占用cpu
python多线程 不适合cpu密集操作型的任务(并无提高),适合io操作密集型的任务
# 启用多进程
import multiprocessing
import time,threading
def thread_run():
print(threading.get_ident())
def run(name):
time.sleep(2)
print('hello', name)
t = threading.Thread(target=thread_run,) # 在进程里创建线程
t.start()
print(__name__)
if __name__ == '__main__':
for i in range(10):
p = multiprocessing.Process(target=run, args=('bob %s' %i,)) # 创建多进程
p.start()
# p.join()
8核,同一时间只能运行8个进程
os.getpid() 获取当前进程id
os.getppid() 获取父进程id
2. 进程的Queue,可允许父进程与子进程间queue访问,或子进程之间,进程间数据传递
from multiprocessing import Process, Queue
import threading
import queue # 线程queue
# def f(q):
# q.put([42, None, 'hello'])
def f(qq):
print("in child:",qq.qsize())
qq.put([42, None, 'hello'])
if __name__ == '__main__':
# q = queue.Queue()
q = Queue() # 创建多进程的queue
q.put("test123")
#p = threading.Thread(target=f,)
p = Process(target=f, args=(q,)) # 将queue传给进程
p.start()
p.join()
print("444",q.get_nowait())
print("444",q.get_nowait())
# prints "[42, None, 'hello']"
#print(q.get()) # prints "[42, None, 'hello']"
3. 管道pipe,进程间数据传递
# 管道pipe,数据传递
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello from child']) # 发信息
conn.send([42, None, 'hello from child2'])
print("from parent:",conn.recv()) # 收信息
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # 收信息
print(parent_conn.recv()) # 收信息
parent_conn.send("张洋可好") # 发信息
p.join()
4. manager,进程间共享数据,即多个进程可以修改同一份数据
# manager 进程间共享数据
from multiprocessing import Process, Manager
import os
def f(d, l):
d[os.getpid()] =os.getpid()
l.append(os.getpid())
print(l)
if __name__ == '__main__':
with Manager() as manager: # 创建manager对象
d = manager.dict() # {} # 生成一个manager字典,可在多个进程间共享和传递
l = manager.list(range(5)) # 生成一个manager列表,可在多个进程间共享和传递
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l)) # 创建10个子进程,分别处理d,l
p.start()
p_list.append(p)
for res in p_list: # 等待结果
res.join()
print(d)
print(l)
5. 进程锁lock,多进程虽然数据不共享,但是共享屏幕,进程锁可以使屏幕打印一次只有一个进程
6. 进程池Pool,同时允许n个进程运行
# 进程池,同时允许n个进程运行
from multiprocessing import Process, Pool, freeze_support
import time
import os
def Foo(i):
time.sleep(1)
print("in process", os.getpid())
return i + 100
def Bar(arg):
print('-->exec done:', arg, os.getpid())
if __name__ == '__main__':
freeze_support() # windows上必须写
pool = Pool(processes=3) # 生成进程池,允许同时放入3个进程
print("主进程",os.getpid())
for i in range(10):
pool.apply_async(func=Foo, args=(i,), callback=Bar) # callback=回调,执行完func后再执行
# pool.apply(func=Foo, args=(i,)) # 异步,串行,在进程池中放入进程
# pool.apply_async(func=Foo, args=(i,)) # 同步,并行
print('end')
pool.close() # 只能先close后join,原因未知
pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。