进程的相关知识

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 import 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>通过集成的方式去开启多个子进程
class 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
import time


def func():
    for i  in range(10):
        time.sleep(0.02)
        print("儿子在这里")

if __name__ == "__main__":
    p = Process(target=func)
    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("子进程是不是守护进程",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个子进程全部完事以后,在执行主程序的代码,效果是完全不一样的
原文地址:https://www.cnblogs.com/ljc-0923/p/9625419.html