day12学python

多进程(不同进程不可直接访问数据)

引入(多进程套线程)

多进程 需导入multiprocessing模块

模板示例1

import threading,time,multiprocessing
def run(name):
    time.sleep(2)
    print('hi',name)
def running(n):
    time.sleep(2)
    print('ok',n,threading.get_ident())
    t=threading.Thread(target=run,args=(n,))
    t.start()
if __name__ == '__main__':
    start=time.time()
    t=[]
    for i in range(10):
        m=multiprocessing.Process(target=running,args=('cf%s'%i,))
        m.start()
        t.append(m)
    for i in t:
        i.join()
    print(time.time()-start)

 注意:

1threading.get_ident()得到当前线程号

2multiprocessing的实例化与函数用法大致与线程threading相同

3if __name__ == '__main__':类似于其它语言的main函数

模板示例2

import time,multiprocessing,os
def a(title):
    print(title)
    print('module_name',__name__)
    print('父进程:',os.getppid())
    print('当前进程',os.getpid())
    print('\n')
def b(name):
    print(name)
    a('\033[31;1mhello it\'s me\033[0m')
if __name__=='__main__':
    a('\033[32;1mhello it\'s me\033[0m')
    m=multiprocessing.Process(target=b,args=('ok',))
    m.start()

 注意:

1 '\033[31;lm字符串\033[0m'颜色输入 

扫描二维码关注公众号,回复: 5712591 查看本文章

2 此程序导入了os包 使用其中os.getpid()代表取到当前进程名 os.getppid()函数 代表取到当前进程的父进程名

======================================================================

1.Queue模块

queue和Queue区别:

①queue是线程间数据共享 用在threading线程中直接使用访问

②Queue是进程间数据传递 用在multiprocessing多进程中(两份数据 经过pickle编码 实现数据一致)

from multiprocessing import Process,Queue
def f(qq):
    qq.put([1,'23','sdad'])
if __name__=='__main__':
    q=Queue()
    p=Process(target=f,args=(q,))
    p.start()
    print(q.get())
    p.join()

 注意:

1from multiprocessing import Process,Queue  从多进程模块中导入Queue模块

2实例化 q=Queue()  后可作为参数传递入其他进程

3Queue(用于进程)与queue(用于线程)一样 put函数可塞入各种类型的数据

 =========================================================================

2.Pipe模块

①用作进程间的数据传递(两份数据 经过pickle编码 实现数据一致)

 示例

from multiprocessing import Process,Pipe
def f(n):
    print(n.recv())
    n.send("it's me")
if __name__=='__main__':
    A,B=Pipe()
    m=Process(target=f,args=(B,))
    m.start()
    A.send("hello")
    print(A.recv()) 

 注意:

1 Pipe模块也是从多进程模块中载入

2 A,B=Pipe() 实例化 Pipe后 得到两个值 分别代表要连接的两个进程

3 两进程间靠send与recv相互传递类似于socket用法

 ======================================================================

3.Manager模板

①利用manager实现数据的共享 做到多个进程修改同一个数据
from multiprocessing import Process,Manager
import os def f(d,k): d[os.getpid()]=os.getpid() k.append(os.getpid()) print(k) if __name__=='__main__': m=Manager() d=m.dict() #生成一个字典可在多个进程间共享和传递 k=m.list() #生成一个列表可在多个进程间共享和传递 li=[] for i in range(10): p = Process(target=f, args=(d, k)) p.start() li.append(p) for n in li: n.join() print(d) print(k)

注意:

1 Manager亦是从多线程模板导入

m=Manager() 实例化得到一个返回值 以此可创建不同的字典.dict()与列表.list()  [只有在Manager中才可对实例化对象创造字典与列表]

3 字典加数据 直接d[key]=value

 进程池pool

from multiprocessing import Process,Pool    #导入进程池模块
import time,os
def f(i):
    time.sleep(2)
    print(i)
    return i+1000
def g(arg):
    print("in end -%s"%os.getpid(),arg)
if __name__=='__main__':
    pool=Pool(processes=3)            #允许进程同时放入3个进程(其余线程等待)
    print('主线程',os.getpid())
    for i in range(10):
        #pool.apply(func=f,args=(i,))    #apply调用串行函数
        #pool.apply_async(func=f,args=(i,))#apply_async调用并行
        pool.apply_async(func=f,args=(i,),callback=g)  #最后增加callback实现 在前函数调用结束后再调用的函数 会传入参数(参数是前函数的返回值)
    print('end ---')
    pool.close()        #进程池 必须要先调用close关闭 在调用join函数
    pool.join()
    

注意:

1 from multiprocessing import Process,Pool    #导入进程池pool模块

pool=Pool(processes=3)   以此种方式实例化进程池 参数为同时放入的最大进程数

3 有两种调用函数 pool.apply(func=f,args=(i,))       此为串行(一个进程结束后 另一进程继续)

        pool.apply_async(func=f,args=(i,))    此为并行(同时进行)

4  pool.apply_async(func=f,args=(i,),callback=g)   最后增加callback实现 在前函数func调用结束后再调用函数 会传入参数(参数是前函数的返回值)

5 进程池必须先close关闭 再调用join函数

    -----若先调用join会报错

    -----只调用close会结束主进程后退出 不会执行完其他进程

#queue和Queue区别(不同进程不可直接访问数据)
#queue是线程间数据共享 用在threading线程中直接使用访问
#Queue是进程间数据传递 用在multiprocessing多进程中(两份数据 经过pickle编码 实现数据一致)

猜你喜欢

转载自www.cnblogs.com/cc123nice/p/10618162.html