zoukankan      html  css  js  c++  java
  • 攻克python3-进程

    进程

    进程是程序的一段执行过程,是个动态概念,是操作系统调度的最小单位。

    multiprocessing模块

    Process 类用来描述一个进程对象。创建子进程的时候,只需要传入一个执行函数和函数的参数即可完成 Process 示例的创建。

      star() 方法启动进程

      join() 方法实现进程间的同步,等待所有进程退出。

      close() 用来阻止多余的进程涌入进程池 Pool 造成进程阻塞。

    multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

      target 是函数名字,需要调用的函数

      args 函数需要的参数,以 tuple 的形式传入

    创建子进程

    直接调用

    from multiprocessing import Process
    import time
    def f(name):
        time.sleep(2)
        print('hello', name)
     
    if __name__ == '__main__':
        p = Process(target=f, args=('bob',))
        p.start()
        p.join()

    继承式调用

    from multiprocessing import Process
    import time
    class MyProcess(Process):
        def __init__(self,name):
            super().__init__()
            self.name=name
     
        def run(self):
            print('task <%s> is runing' % self.name)
            time.sleep(2)
            print('task <%s> is done' % self.name)
     
    if __name__ == '__main__':
        p=MyProcess('egon')
        p.start()
     
        print('')

    与线程一样run方法必须重写

    进程间通信

    这里介绍只有具有亲缘关系的进程才能进行通信。

    进程queue

    线程queue共用内存空间
    进程queue不共用内存空间,只是通过传递数据来达到进程间通信的目的

    from multiprocessing import Process,Queue
    import threading,queue
    
    def fun(qq):
        qq.put("wurui")
    
    if __name__ == '__main__':
        q=Queue()
        # q=queue.Queue()
        p=Process(target=fun , args=(q,))
        p.start()
        print(q.get())
        p.join()
    View Code

    管道通信pipe

    from multiprocessing import Process,Pipe
    
    def f(conn):
        conn.send("hello!")
    
    if __name__ == '__main__':
        p_conn,c_conn=Pipe()
        p=Process(target=f,args=c_conn)
        p.start()
        print(p_conn.recv())
        p.join()
    View Code

    manager

    A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies.

    A manager returned by Manager() will support types listdictNamespaceLockRLockSemaphoreBoundedSemaphoreConditionEventBarrierQueueValue and Array. For example:

    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 m:
            d=m.dict()
            l=m.list(range(5))
            p_list=[]
            for i in range(10):
                p=Process(target=f,args=(d,l))
                p.start()
                p_list.append(p)
            for j in p_list:
                j.join()
            print(d)
            print(l)
    View Code

    lock(屏幕锁:防止一个进程未打印完成,另一个进程插入)

    def f(l,i):
        l.acquire()
        print("hello",i)
        l.release()
    
    if __name__ == '__main__':
        l=Lock()
    
        for i in range(10):
            Process(target=f,args=(l,i)).start()
    View Code

    进程池

    在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,10几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,这时候进程池Pool发挥作用的时候就到了。

    Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。

    from  multiprocessing import Process, Pool,Lock
    import time
    import os
    
    '''
    如何在进程池中使用进程锁
    '''
    def Foo(i):
        # l.acquire()
        time.sleep(2)
        print("in process",os.getpid())
        # l.release()
        return i + 100      #返回值由回调函数接收
    
    def Bar(arg):
        print('-->exec done:', arg,os.getpid())
    
    if __name__ == '__main__':
        pool = Pool(processes=3) #允许进程池同时放3入个进程
        # l = Lock()
        print("主进程",os.getpid())
        for i in range(10):
            pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback=回调
            #pool.apply(func=Foo, args=(i,)) #串行
            #pool.apply_async(func=Foo, args=(i,)) #并行
        # print('end')
        pool.close()    #先close在join
        pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。.join()
    View Code
    • pool.apply_async()用来向进程池提交目标请求。
    • pool.join()是用来等待进程池中的worker进程执行完毕,防止主进程在worker进程结束前结束。但pool.join()必须使用在pool.close()或者pool.terminate()之后。
    • close()terminate()的区别在于close()会等待池中的worker进程执行结束再关闭pool,而terminate()则是直接关闭。
    • result.successful()表示整个调用执行的状态,如果还有worker没有执行完,则会抛出AssertionError异常。    
    • 利用multiprocessing下的Pool可以很方便的同时自动处理几百或者上千个并行操作,脚本的复杂性也大大降低.
  • 相关阅读:
    redis中的发布订阅(Pub/Sub)
    emmc基础技术8:操作模式3-interrupt mode
    Linux命令-tar
    git获取内核源码的方法
    Linux内核基础设施
    Linux内核简介
    emmc基础技术8:操作模式2-device identification mode
    内核子系统文档撰写方法
    eMMC基础技术6:eMMC data读写
    eMMC基础技术10:寄存器介绍
  • 原文地址:https://www.cnblogs.com/kxsph/p/9237983.html
Copyright © 2011-2022 走看看