zoukankan      html  css  js  c++  java
  • multiprocessing模块

    multiprocessing模块

    由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。
    multiprocessing包是Python中的多进程管理包。与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。该进程可以运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。

    process

    构造方法:

    Process([group [, target [, name [, args [, kwargs]]]]])

    group:线程组,目前还没有实现,库引用中提示必须是None;

    target:要执行的方法

    name:进程名

    args/kwargs:要传入方法的参数

    实例方法:

    is_alive():返回进程是否在运行

    join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。
     
    start():进程准备就绪,等待CPU调度

    run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。
     

    terminate():不管任务是否完成,立即停止工作进程

    属性

    daemon:和线程的setDeamon功能一样守护进程

    name:进程名字。

    pid:进程号。

    • Python的进程调用
    from multiprocessing import Process
    import time
    def foo(q):
        time.sleep(1)
        print(q)
    
    if __name__=="__main__":
    
        l=[]
        for i in range(3):
    
            p=Process(target=foo,args=("W"))
            l.append(p)
            p.start()
        for i in l:
            i.join()
        print("end")
    
    "D:Program Filespython.exe" E:/py_code/进程队列/进程队列.py
    W
    W
    W
    end
    
    Process finished with exit code 0
    
    

    上述进程的调用是比较常规的调用。

    • Proscess继承类
    from multiprocessing import Process
    import time
    class MyProcess(Process):
        def __init__(self):
            super(MyProcess, self).__init__()
            # self.name = name
    
        def run(self):
    
            print ('hello', self.name,time.ctime())
            time.sleep(1)
    
    
    if __name__ == '__main__':
        p_list=[]
        for i in range(3):
            p = MyProcess()
            p.start()
            p_list.append(p)
        for p in p_list:
            p.join()
        print('end')
    
    
    "D:Program Filespython.exe" E:/py_code/进程队列/进程队列.py
    hello alvin:1 Thu Jul 20 18:07:56 2017
    hello alvin:0 Thu Jul 20 18:07:56 2017
    hello alvin:2 Thu Jul 20 18:07:56 2017
    end
    
    Process finished with exit code 0
    
    
    
    
    

    上面的代码定义了一个类并继承了一个进程,并开启了5个进程,这5个进程会均会执行MyProcess类中的run方法即打印 ('hello',self.name,time.ctime())。

    • 进程间的通讯(Queue)
    from multiprocessing import Process,Queue
    import queue
    
    def foo(q):
        q.put("1")
    
    def bar(q):
    
        print(q.get(),"ok")
    
    if __name__=="__main__":
        q=Queue()  #相等于q=queue.Queue()
        for i in range(3):
            p=Process(target=foo,args=(q,))
    
            p1=Process(target=bar,args=(q,))
            p1.start()
            p.start()
    
    "D:Program Filespython.exe" E:/py_code/进程队列/进程队列.py
    1 ok
    1 ok
    1 ok
    
    Process finished with exit code 0
    
    • 管道(pipe)

    管道()函数返回由管道连接的一对连接对象,该管道默认是双向的(双向的)。例如:

    def foo(o):
        data=o.recv()
        print(data)
        o.send("hey!whatmini")
    
    
    
    if __name__=="__main__":
        sock,conn=Pipe()#sock与conn相当于管道的两个接口
    #
        t1=Process(target=foo,args=(conn,))
        t1.start()
        sock.send("你好")  
        print(sock.recv())
        
    
    "D:Program Filespython.exe" E:/py_code/进程队列/进程队列.py
    你好
    hey!whatmini
    
    Process finished with exit code 0
    
        
        
    

    需要注意的是:Pipe()返回的两个连接对象代表管道的两端。 每个连接对象都有send()和recv()方法(等等)。 请注意,如果两个进程(或线程)尝试同时读取或写入管道的同一端,管道中的数据可能会损坏

    manager

    Queue和pipe只是实现了数据交互,并没实现数据共享,即一个进程去更改另一个进程的数据。

    from multiprocessing import Process, Manager
    
    def foo(l,i):
        l.append(i*i)
    
    if __name__ == '__main__':
    
        with Manager() as manager:
    
            manager=Manager()
    
            l = manager.list([11,22,33])  #创建一个列表也可以字典类型都支持
            p_list = []
            for i in range(10):
                p = Process(target=foo, args=(l,i))
                p.start()
                p_list.append(p)
    
            for res in p_list:
                res.join()
    
            print(l)
    
    "D:Program Filespython.exe" E:/py_code/进程队列/进程队列.py
    [11, 22, 33, 4, 1, 9, 36, 81, 0, 49, 16, 64, 25]
    
    Process finished with exit code 0
    
    进程池

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

    from multiprocessing import Pool   #
    import time
    
    def foo(args):
     time.sleep(1)
     print(args)
    
    if __name__ == '__main__':
     p = Pool(5)   #进程池对象的最大量为5个
     for i in range(30):  #30个任务5个进程对象去执行
         p.apply_async(func=foo, args= (i,))  #异步执行
    
     p.close()   # 等子进程执行完毕后关闭线程池
     # time.sleep(2)
     # p.terminate()  # 立刻关闭线程池
     p.join()  #主进程等待所有子进程执行完毕,必须在close或terminate之后
     
    
    

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

    进程池中有以下几个主要方法:

    1 apply:从进程池里取一个进程并执行

    2 apply_async:apply的异步版本

    3 terminate:立刻关闭线程池

    4 join:主进程等待所有子进程执行完毕,必须在close或terminate之后

    6 close:等待所有进程结束后,才关闭线程池

  • 相关阅读:
    winform 关于Messagebox自动定时关闭
    Git常用命令
    使用消息队列异步化系统
    在Servlet(或者Filter,或者Listener)中使用spring的IOC容器
    基于Annotation与SpringAOP的缓存简单解决方案
    Ant自动构建
    Quartz定时调度
    Sybase数据库的分页功能
    oracle 日期相减
    n个List<Map>合并,Map中某属性值相等的value值相加
  • 原文地址:https://www.cnblogs.com/lijian-22huxiaoshan/p/7215279.html
Copyright © 2011-2022 走看看