Python学习---进程 1225

进程创建

进程创建:

      第一种:直接创建

      第二种;利用类来实现

第一种:直接创建

from multiprocessing import Process
import time
def f(name):
    time.sleep(2)
    print('hello', name, time.ctime())
if __name__ == '__main__':
    li = []
    for i in range(13):  # 文件内有4个进程,同时并发工作:主进程 + 3个进程
        p = Process(target=f, args=('world',))  # 创建进程对象
        li.append(p)
        p.start()
    for i in li:
        i.join()
    print('end')

image

第二种;利用类来实现

import time
from multiprocessing import  Process
class MyProcess(Process):
    # def __init__(self, name):  默认有名字
    def __init__(self):
        super(MyProcess, self).__init__()
        # self.name = name
    def run(self):
        time.sleep(1)
        print('hello', self.name, time.ctime()) # 进程自己有name,所以可以不用设定
if __name__ == '__main__':
    li = []
    for i in range(3):
        # p = MyProcess(str(i))
        p = MyProcess()         # 进程默认有名字
        p.start()
        li.append(p)
    for i in li:
        i.join()
    print("end")

image

父子进程:

父子进程:

from multiprocessing import Process
import os
import time
def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())
    print('process id:', os.getpid())

def f(name):
    info('\033[31;1mfunction f\033[0m')
    print('hello', name)

if __name__ == '__main__':      # Win7下必须添加这个,否则会报错
    info('\033[32;1mmain process line\033[0m')
    time.sleep(10)
    p = Process(target=info, args=('\033[32;1mson process\033[0m',))
    p.start()
    p.join()

image

进程通信

进程通信:

    1 Pipes  

    2 Queues

Pipes:实现通信: 将父进程作为参数传递个子进程,子进程通过send发送消息给父进程

from multiprocessing import Process, Pipe
def f(conn):
    conn.send([12, 34, 56])
    # conn.send([12, 34, 56])  
    conn.close()
if __name__ == '__main__':
    parent_conn, child_conn = Pipe()  # 类似Socket,返回主进程,子进程的通行管道
    p = Process(target=f, args=(child_conn, ))
    p.start()
    p2 = Process(target=f, args=(child_conn, ))
    p2.start()
    print(parent_conn.recv())  # 主进程接收的信息
    print(parent_conn.recv())  # 发送了2个所以接收2个
    p.join()

image

Queues:实现通信: 子进程复制了父进程。父进程将Queue对象pickle序列化后交个子进程反pickle

from multiprocessing import Process, Queue
import time
def f(q, name):
    q.put([50, name, 'world'])
    print('Func Q:', id(q))
if __name__ == '__main__':
    li = []
    q = Queue()
    q.put([12, 'heh', 'world'])
    print('Main Q:', id(q))
    for i in range(3):  # 文件内有4个进程,同时并发工作:主进程 + 3个进程
        p = Process(target=f, args=(q, i))  # 创建进程对象,同时子进程操作父进程的队列
        li.append(p)
        p.start()
    print(q.get())  # 父进程来获取子进程传递的
    print(q.get())  # 子进程复制了父进程。父进程将Queue对象pickle序列化后交个子进程反pickle
    print(q.get())
    print(q.get())
    for i in li:
        i.join()
    print('end')

image

进程数据共享

Manager

from multiprocessing import Process, Manager

def f(d, l,n):
    d[n] = '1'
    d['2'] = 2
    d[0.25] = None
    l.append(n)
    # print(l)
if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(5))
        p_list = []
        for i in range(10):
            p = Process(target=f, args=(d, l,i))
            p.start()
            p_list.append(p)
        for res in p_list:
            res.join()
        print(d)
        print(l)

进程池

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

进程池中有两个方法:

      1、 apply

      2、 apply_async

from  multiprocessing import Process, Pool
import time
def Foo(i):
    time.sleep(2)
    return i + 100
def Bar(arg):
    print('-->exec done:', arg)
pool = Pool(5)
for i in range(10):
    pool.apply_async(func=Foo, args=(i,), callback=Bar)
    # pool.apply(func=Foo, args=(i,))
print('end')
pool.close()
pool.join()

【更多参考】http://www.cnblogs.com/yuanchenqi/articles/5745958.html

【更多参考】https://www.cnblogs.com/alex3714/articles/5230609.html

posted @ 2018-07-29 09:05  小a玖拾柒  阅读(234)  评论(0编辑  收藏  举报