进程的相关知识

1,对多进程的模块:  multiprocess   Process是进程的模块

  form multiprocessing import Process从multiprocessing包中导入Process模块

  multiprocess是python中的一个操作管理进程的一个包,multi是取自multiple的多功能的意思,在这个包中,几乎包含了和进程操作的所有模块,有与子模块非常多,为了方便大家学习可以分为四个部分:创建进程部分,进程池部分,进程同步部分,进程之间数据共享

2,进程的并行与并发

  2.1>并行:是指两者同时执行,好比有2条车道,在某一时间点(比如说下午3:58)两条车道上都有车在跑:(资源够用,比如三线程,四核CPU)

  2.2.>并发:是指资源有限的情况下,两者交替轮流使用资源,比如只有一条车道(单核CPU资源),name就是A车先走,在某个时刻A车退出,把车道让给B车,B车走完,继续给A车使用

  2.3>区别:并行是从微观上,也就是在一个精确的时间片刻,有不同的成序在执行,这就要求必须要求有多个处理器  

      并发:是从微观上来看,在一个时间段上可以看出是通同时执行,比如一个服务器同时处理多个session

    注意:早期单核CPU的时候,对于进程也是微观上串行(站在cpu角度看),宏观上是并行(站在人的角度有喝多程序在执行,那是因为CPU处理速度太快,你感受不到)

  2.4>同步:一个人物的完成任务时,需要依赖另一个,只有等待另一个任务完成时,依赖的任务才能算完成,这时一种可靠的任务序列,要么成功都成功,失败都失败,两个任务的状态保持一致

  2.5>异步:是不需要被等待的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了,整个任务就算完成了,至于被依赖的任务最终是否真正完成,依赖它 的任务无法完成,所以它是不可靠的任务序列

  2.6>阻塞和非阻塞这两个概念与程序等待消息通知是的状态有关,也就是说阻塞与非阻塞主要是程序等待消息是的状态的角度来说的

  

就绪状态是在只要从新开始执行程序都会进入到就绪状态(阻塞的时候和启动程序的时候)

3,进程的开启:

  3.1>使用函数来开启子进程

    from multiprocessing impport Process......................导入Process这个模块

    import os ....................................导入os这个模块

    import time...................................导入时间模块

    def func(n):........................定义一个函数

      time.sleep(1).....................休眠1秒

      print("执行到我了...我的pid值是:%s,我父进程(主进程)的pid的只是:%s" %(os.getpid(),os.getppid()))....os.getpid()和os.getppid()是查找进程的pid值,每个运行的程序都会有一个独立的pid值,os.getppid()是获得父进程的pid值

    if __name__ == "__main__":.................表示在windows系统当前模块的__name == __main__的时候执行以下代码 

      p = Process(target = func,args = (1,))..........Process其实是一个类,此时是实例化一个Process类的对象

      p.start()..................是启动一个子进程(是通过python解释器发送给操作系统帮开一个子进程) 进程的就绪状态

      time.sleep(2)..........休眠2秒,此时如果子进程和父进程休眠时间不一样,谁时间短就先执行谁,一样的话就没准了.

      print("我是主进程...我自己的pid值是:%s,此时我的父进程的pid的值是:%s" % (os.getpid(),os.getppid()))

  3.2>通过继承的方式来开启子进程

    from multiProcessing import process  

    class MyProcess(Process):..............自定义一个类名但是要继承Process类,因为Process里有_popen属性

      def __init__(self):

        super(MyProcess,self).__init__()............调用父类的__init__方法

        print("执行到这了...")

      def run(self):.......................定义一个run方法

        print("这是以继承类的方式开启的子进程")

    if __name__ == "__main__":......同样的在windows操作系统中只有当模块中的条件满足执行以下带代码

      p1 = MyProcess().....................实例化定义类的对象

      p1.start()....开启一个子进程(是通过python解释器去告诉操作系统帮开一个子进程)  就绪状态

      p1.run()...............是直接干预操作系统进而直接先执行Process中的run方法开启一个子进程执行run方法

      print("我是父进程...")

  3.3>开启多个子进程

    from multiProcessing import Process

    def func(n):

      print("这是子进程%s"%n)

    if __name__ == "__main__":

      for i in range(3):................for循环是去开启子进程的个数

        p = Process(target=func,args =(i,)),....此时的target = 后边跟的是上边的函数名,args=后边是for循环次数的参数

        p.start()

        print("这是父进程%s"%i)

  3.4>通过集成的方式去开启多个子进程

    from multiprocess import Process

    calss MyProcess(Process):

      def __init__(self,count):

        super(MyProcess,self).__init__():

        self.count = count

      def run(self):

        print("这是子进程%s"%self.count)

      if __name__ == "__main__":

        for i in range(3):

          p = MyProcess(i).................实例化对象去传参数

          p. start()

          print("这里是父进程%s"%i)

 4,进程的其他常用操作

  is_alive().................................判断子进程是否在执行返回的值是bool值(在开启子进程之后才能判断是否活着)

  terminate()...............................杀死进程(杀死的是子进程)杀子进程需要一定的时间,网络传输就是有许多的不确定性

5,进程的start,和join

  from multiprocessing import Process

  def func():

    for i  in range(10):

      time.sleep(0.02)

      print("儿子在这里")

  if __name__ == "__main__":

    p.start()

    p.join().....................当join的时候就会把子进程运行完,再运行主进程(是异步变同步)主进程进行到到这就会阻塞

    for i in range(5):

      time,sleep(0.01)

      print("爸爸在这里")

当进的时候有多个子进程,也会等子进程全部运行完再执行主进程的代码.

p.join是让主进程等待子进程执行完,现象:主进程执行到这句话,主进程阻塞,等待子进程执行

父进程执行执行join,就会变成同步,不执行join,父进程和子进程就是异步的关系

join()必须放在start()的后边

6,进程的长用属性

  6.1>从主进程获得子进程的相关信息

    from multiprocessing import Process

    import os

    def func():

      print("这里是子进程,我自己的pid值是%s"%os.getpid())

    if __name__ == "__main__":

      p = Process(target=func)

      p.start()

      p.name = "liangxue"...........................给当前这个子进程命名名字,当从新开启一个进程可以再重新命名

      print("子进程的名字时%s"%p.name)..................查询这个名字

      print("子进程的pid值是:%s"p.pid).....................此2获得的daemon值是从子进程的os.getpid得来的

      print("子进程是不是守护进程"p.daemon)......................False

  6.2>守护进程(是在start(之前静实例化的对象设置为守护进程))

  from multiprocessing import Process

  import time

  def func():

    time.sleep(0.1)

    print("我是子程,同时我也是守护进程")

  if __name__ == "__main__":

    p = Process(target = func)

    p.daemon = True...........此时表示将开启的这个子进程设定为守护进程False是为正常进程,必须在开启子进程之前进行,将接下来的子进程变为守护进程.daemon的默认值是False

    p.start()

    time.sleep(0.5)

    print("我这里是主进程")

守护进程的2个特点:

  1>守护进程会随着父进程结束而结束

  2>守护进程不能再创建子进程

7,多个子进程之间无法共享内存

  from multiprocessing  import Process

  import time

  import random

  def func(i):

    print("我是%s"%i)

  if __name__ =="__main__":

    l = [ ]

    addr = ["河南的","山东","辽宁的","湖南的"]

    for  i in addr:

      p = Process(target=func,args=(i,))

      p.start()

      l.append(p)

    [p.join() for p in l].........用列表推导式来同时join主四个子进程,目的就是等四个主进程都完毕了再执行主进程

    time.sleep(1)

    print("我选%s"%random.choice(addr)))等子进程都执行完毕后再执行主进程

每个子进程都是相对独立的个体,他们之间的资源不能共享.join不能再for循环里边,要放到一个列表中再用列表推导式,一次join主等4个子进程全部完事以后,在执行主程序的代码,效果是完全不一样的

    

      

  

     

    

      

          

猜你喜欢

转载自www.cnblogs.com/ljc-0923/p/9625419.html