• day32 开启进程process的其他方法 进程池


    一、上节回顾

    开启进程:

    from multiprocessing import Process
    import time
    def task(name):
        print("%s is running"%name)
        time.sleep(2)
        print("%s is stopping"%name)
    if __name__=="__main__":#在windows系统下,开启子进程必须写到这一行下面
        p=Process(target=task,args=("egon",))
        p.start() #只是在给操作系统发了一个信号,让操作系统去开启进程(申请内存+拷贝父进程的地址空间)
        print("")

    1、什么是进程?

      进程是一个抽象的概念,进程即正在执行的过程,进程的概念起源于操作系统,

      进程的创建,调度管理都贵操作系统管

    2、操作系统的作用?

      1、管理的硬件,把复杂丑陋的硬件接口封装成良好的接口给客户使用

      2、进程的创建,调度管理都贵操作系统管理

    3、多道技术?

      产生背景:针对单核下实现并发

      核心:

        1、空间上复用(多个进程的内存空间是互相隔离的)

        2、时间上的复用(复用cpu的时间)

    一些小知识:

         cpu 时间片是指的cpu中的一小块时间

      作业讲解中遇到的问题:

      (1)并发是指的任务

      (2)实现服务端的并发

      (3)服务端的作用:建立连接 通信

      (4)开启进程:

      (5)listen是指的操作系统的限制,队列是占用的内存的空间

        第一次握手是指的操作系统从从队列中取走一个回给客户端

      (6)操作系统不仅干TCP建立连接的活,还要做其他的工作

      (7)一个server对象产生一个端口建立连接

      (8)一个服务端于多个客户端实现并发

      (9)进程的开启,是占用内存空间,不可能无限的开启进程,客户端有可能会开启一个上百万的进程

    二、新内容

    (一、开启进程)

     1、进程的两种方式

    # # 方式一
    from multiprocessing import Process
    import time
    def task(name):
        print("%s is running"%name)
        time.sleep(2)
        print("%s is stopping"%name)
    if __name__=="__main__":#在windows系统下,开启子进程必须写到这一行下面
        p=Process(target=task,args=("egon",))
        p.start() #只是在给操作系统发了一个信号,让操作系统去开启进程(申请内存+拷贝父进程的地址空间)
        print("")
    开启进程的方式一
     方式二(不重要,不符合规范)
    from multiprocessing import Process
    import time
    class Myprocess(Process):
        def __init__(self,name):
            super().__init__()
            self.name=name
        def run(self):
            time.sleep(2)
            print("%s is running"%self.name)
            time.sleep(3)
    if __name__=="__main__":
        p=Myprocess("egon")
        p.start()
        print("")
    开启进程的方式二

    2、python解释器相当于一个函数,将写的代码编程能运行的程序

      一个程序运行两遍就是两个进程,就相当于一个py关掉又运行了一次(讲特性(线程)的时候会用到)

    import time,os
    print(os.getpid(),os.getpid())
    time.sleep(10)
    
    #python3 test.py----->python.exe

    3、僵尸进程:父进程,结束进程还存在

          正常存在是先是子进程结束,然后结束父进程

      重要点:start  join

          确定子进程结束之后才会进行主进程  使用join()

          开启进程的方法 p.start()  只是传递信号给操系统,并没有顺序

          没有办法实现顺序执行

    from multiprocessing import Process
    import time
    def task(name):
        print("%s is running"%name)
        time.sleep(2)
    if __name__=="__main__":
        p1=Process(target=task,args=("egon",))
        p2=Process(target=task,args=("alex",))
        p3=Process(target=task,args=("yxxx",))
        p_1=[p1,p2,p3]
        for p in p_1:
            p.start()
        for p in p_1:
            p.join()
        print("")
    开启先开启子进程后主进程

    4、作为了解

    from multiprocessing import Process
    import time
    def task(name):
        print("%s is running"%name)
        time.sleep(2)
    if __name__=="__main__":
        p1=Process(target=task,args=("egon",),name="xxxxx")
        p1.start()
        print(p1.name)
        print(p1.pid)  #子进程 ID
        p1.join()     #先子进程后主进程
        p1.terminate()  #强行终止子进程
        print(p1.is_alive()) #判断子进程是否还存在
        print("")
    View Code

     5、参数介绍

    1 group参数未使用,值始终为None
    2 
    3 target表示调用对象,即子进程要执行的任务
    4 
    5 args表示调用对象的位置参数元组,args=(1,2,'egon',)
    6 
    7 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
    8 
    9 name为子进程的名称

     方法介绍:

    1 p.start():启动进程,并调用该子进程中的p.run() 
     2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法  
     3 
     4 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
     5 p.is_alive():如果p仍然运行,返回True
     6 
     7 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程  

      属性介绍:

    1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
    2 
    3 p.name:进程的名称
    4 
    5 p.pid:进程的pid
    6 
    7 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
    8 
    9 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)

    (二、进程池)

    提交/调用任务的方式有两种:

      同步调用:提交/调用一个任务,然后就在原地等着,等到该任务执行完毕拿到结果,再执行下一行代码

      异步调用:提交/调用一个任务,不在原地等着,直接执行下一行代码,结果?

    1、异步调用

    # from multiprocessing import Process,pool
    from concurrent.futures import ProcessPoolExecutor
    import time,random,os
    def piao(name):
        print("%s is piaoing %s"%(name,os.getpid()))
        time.sleep(random.randint(1,4))
    
    if __name__=="__main__":
        p=ProcessPoolExecutor(4)
        for i in range(10):
            p.submit(piao,"alex %s"%i)
    
        #关门+等
        #pool.close()
        #pool.join()
        p.shutdown(wait=True)
        print("",os.getpid())
    异步调用

    说明:

    同时进行的进程一共有四个,四个同时进行(一共造出四个进程,就是有四个ID)

    for循环丢进进程只是发出一个信号

    2、同步调取结果:

    3、异步调取结果

    # from multiprocessing import Process,pool
    from concurrent.futures import ProcessPoolExecutor
    import time,random,os
    def piao(name,n):
        print("%s is piaoing %s"%(name,os.getpid()))
        time.sleep(1)
        return n ** 2
    
    if __name__ == '__main__':
        p=ProcessPoolExecutor(4)
        objs=[]
        start=time.time()
        for i in range(10):
            # res=p.submit(piao,'alex %s' %i,i).result() #同步调用
            # print(res)
            obj=p.submit(piao,'alex %s' %i,i) #异步调用
            objs.append(obj)
    
        for obj in objs:
            print(obj.result())
    
        stop=time.time()
        print(stop-start)
        # 关门+等
        # pool.close()
        # pool.join()
        p.shutdown(wait=True)
        print('',os.getpid())
    异步调取结果

    异步调取结果不影响并发的执行:

    4、时间的计算:开启进程也需要花费时间,切换的时间,操作系统创建进程申请拷贝空间的时间

      开启进程数量越多花费的时间越短(在机器可承受的范围之内的情况下)

    from multiprocessing import Process
    import time,random,os
    def piao(name,n):
        print("%s is piaoing %s"%(name,os.getpid()))
        time.sleep(1)
        return n**2
    if __name__=="__main__":
        start=time.time()
        p_1=[]
        for i in range(10):
            p=Process(target=piao,args=("ss",1))
            p_1.append(p)
            p.start()
            
        for p in p_1:
            p.join()
            
        stop=time.time()
        print(stop-start)
    时间的计算

  • 相关阅读:
    Ugly Numbers
    Present
    Out of Hay
    Stars(树状数组或线段树)
    Humble Numbers
    Wireless Network
    Rank List
    Argus
    食物链
    Antenna Placement
  • 原文地址:https://www.cnblogs.com/number1994/p/8157726.html
Copyright © 2020-2023  润新知