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()  # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
posted @ 2020-07-04 22:40  Jerome12138  阅读(187)  评论(0编辑  收藏  举报