进程

一、进程的初步使用,方法和线程一样,只是类名不同而已,例子如下:

from multiprocessing import Process
import time


def run(name):
    time.sleep(2)
    print('Hello, %s' % name)


if __name__ == '__main__':
    for i in range(10):
        p = Process(target=run, args=('Bob %s' % i,))
        p.start()
进程启动

进程中又启动线程

from multiprocessing import Process
import time
import threading


def thread_run():
    print(threading.get_ident())  # 获取线程ID


def run(name):
    time.sleep(2)
    print('Hello, %s' % name)
    t = threading.Thread(target=thread_run)
    t.start()


if __name__ == '__main__':
    for i in range(10):
        p = Process(target=run, args=('Bob %s' % i,))
        p.start()
进程中包含线程

 获取进程ID,并从以下例子中得出,所有的子进程都有你进程

import os
from multiprocessing import Process


def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process id:', os.getppid())
    print('process id:', os.getpid())
    print('\n\n')


def f(name):
    info('\033[31;1mcalled from child process function f\033[0m')
    print('Hello', name)


if __name__ == '__main__':
    info('\033[1;32mmain process line\033[0m')
    p = Process(target=f, args=('bob',))
    p.start()
获取进程ID

 

二、进程间通讯

1、进程队列(Queue)

(1)、其实进程队列并不能实现数据的共享,只是进程把数据首先经过序列化发给第三方,然后第三方把数据发送给另外一个进程,反序列化,这其实是数据的传递。例子:

from multiprocessing import Process, Queue
q = Queue()


def f(q):  # 注意:进程之间使用队列,必须要使用队列作为参数传递
    q.put([42, None, 'Hello'])


if __name__ == '__main__':
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())
    p.join()
Queue实现进程间通讯

注意:父进程启动子进程时,需要把队列作为参数传递

2、管道(Pipe)

(1)、管道的实现和socket的接发数据差不多,也有recv、send方法,使用步骤如下:

A、定义实例,会返回两个对象,parent_conn,child_conn = Pipe()

B、启动进程时,把child_conn此对象传递给子进程

例子如下:

from multiprocessing import Process, Pipe


def f(conn):
    conn.send('Hello from child1')
    conn.send('Hello from child2')
    print(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('我很好')
    parent_conn.close()
管道

 3、Manager

(1)、Manager可实现多进程间共享

(2)、步骤

A、实例化,manager = Manager()

B、初始化变量,如d = manager.dict()

C、把初始化的变量传递给函数, P = Process(target=func, args=(d,l))

例子:

from multiprocessing import Process, Manager
import os


def fun(d, l):
    d[os.getpid()] = os.getpid()
    l.append(os.getpid())
    print(d)
    print(l)


if __name__ == '__main__':
    manager = Manager()
    d = manager.dict()
    l = manager.list(range(5))
    p_list = []
    for i in range(10):
        p = Process(target=fun, args=(d, l))
        p_list.append(p)
        p.start()
    for p in p_list:
        p.join()
    print(d)
    print(l)
Manager

 

三、进程锁

1、存在的意义:进程之间数据是独立的,为什么还要进程锁?因为进程之间共享了一些资源,如屏幕。。。

2、用法:

(1)、实例化

(2)、把锁作为参数在实例化进程时传递

(3)、lock.acquire()....lock.release()

3、例子:

from multiprocessing import Process, Lock


def hello(l, name):
    l.acquire()
    print('hello ',name)
    l.release()


if __name__ == '__main__':
    lock = Lock()
    for i in range(10):
        p = Process(target=hello, args=(lock, i))
        p.start()
Lock

 

四、进程池

1、作用:和线程的信号量一样,只允许N个进程同时执行。可在实例化时定义。

2、用法:

(1)、实例化 pool = Pool(5)

(2)、pool.apply(func=func_name,args=())  串行

            pool.apply_async(func=func_name,args=()) 并行

(3)、pool.close()

            pool.join()  必须要先close再join

3、例子:

from multiprocessing import Pool
import time
import os


def run(i):
    time.sleep(2)
    print('in the process', os.getpid())
    return i + 100


if __name__ == '__main__':
    pool = Pool(5)
    for i in range(10):
        # pool.apply(func=run, args=(i,))  # 串行
        pool.apply_async(func=run, args=(i,))  # 并行
    pool.close()
    pool.join()  # 必须要先close再join!!
进程池

4、进程池中的回调

(1)、可在pool.apply_async中添加参数callback,则在func参数执行完就执行callback,并且会把func返回的结果传递给callback

例子:

from multiprocessing import Pool
import time
import os


def run(i):
    time.sleep(2)
    print('in the process', os.getpid())
    return i + 50


def bar(arg):
    print('-->exec done:', arg)
    print('process id:', os.getpid())


if __name__ == '__main__':
    print('main process id', os.getpid())
    pool = Pool(3)
    for i in range(10):
        # pool.apply(func=run, args=(i,))  # 串行
        pool.apply_async(func=run, args=(i,), callback=bar)
    pool.close()
    pool.join()  # 必须要先close再join!!
回调

 

posted on 2019-05-30 22:34  Treelight  阅读(144)  评论(0编辑  收藏  举报