• day4.进程


    一、什么是程序

    # 例如qq.ext 放在硬盘上静静的躺在那,这就叫一个程序

    二、什么是进程

    """
    进程就是正在运行的程序,进程是资源分配的基本单位
    双击qq.ext 本来qq.exe是放在硬盘上,但是双击后,开辟一块空间,
    把qq.exe 的相关内容和资源放到了开辟的内存里面,里面装着这个
    程序的指令(2+3)和数据(2 3),这个内存里边的内容就是一个进程
    """

    三、什么是线程

    """
    线程是程序执行的基本单位
    一个进程的指令未必存在一个线程里面,会首先找到主线程,也就是
    我们的mian线程,执行的过程可能有其他的路线
    """
    """
    进程是我需要一些资源,你先在内存帮我分配好,所以它是资源分配的基本单位
    线程是我执行这个程序了,我先从main开始,可能有分支,同步,所以线程是执行
    的基本单位
    """

    四、程序是如何执行的

    """
    例: 有 a=2+3 这么一条指令
    a就是内存的一块空间, 2+3 就理解为程序的数据
    
    Registers: 寄存器
    PC: 程序计数器(存储指令地址)
    ALU: 数学逻辑单元
    
    把 2 和 3 通过内存总线 系统总线放到CPU的寄存器里面,寄存器就是存数据用的
    通过ALU计算为5,放到内存 a=5
    PC就是记录下一条指令执行到哪里了,第一条指令执行完了,PC就指向下一条指令
    
    总结一下:
    假如说 一个线程里面要执行a=2+3,PC计数器指向这条指令,
    首先把2+3放到寄存器里面,,ALU计算最后的结果,
    把最后结果写回到内存里,PC计数器指向下一条指令
    """

    五、创建进程

    1、进程的基本使用

    from multiprocessing import Process
    # (1) 进程的基本使用
    def func():
        print("1.子进程id>>{},2父进程id>>{}".format(os.getpid(),os.getppid()))
    
    # 为了解决windows 和 linux 系统的兼容问题,下面这句话必须加上,否则报错
    if __name__ == "__main__":
        # 创建子进程,返回进程对象,执行func这个任务
        p = Process(target=func)
        # 调用子进程
        p.start()

    2、创建带有参数的进程

    def func(n):
        for i in range(1,n+1):
            print("1.子进程id>>{},2父进程id>>{}".format(os.getpid(),os.getppid()))
    
    if __name__ == "__main__":
        n = 5
        #创建子进程
        p = Process(target=func,args=(n,))
        #调用子进程
        p.start()
    
        for i in range(1,n+1):
            print("*" * i)

    3、进程之间的数据彼此隔离

    from multiprocessing import Process
    import time
    count = 10
    def func():
        global count
        count += 1
        print("我是子进程count={}".format(count))
    
    if __name__ == "__main__":
        p=Process(target=func)
        p.start()
        time.sleep(1)
        print(count)

    4、多个进程之间是异步并发

    """
    多个进程之间是异步并发的程序,因为cpu的调度策略问题,不一定哪个任务先执行,哪个任务后执行.
    整体而言,主进程比子进程创建的速度要快,cpu遇到阻塞会立刻切换任务,等到阻塞态的任务变成了就绪态,cpu再回来执行
    
    主程序会默认等到所有的子程序执行结束之后,在统一关闭程序,释放资源.
    若不等待,有可能在后台存有多个未执行结束的子进程,会变成僵尸进程,不停的占用cpu,内存
    增加系统的压力,所有方便于对进程的管理,主进程默认等待子进程.
    """
    from multiprocessing import Process
    import time, random
    def func(n):
        time.sleep(random.randrange(3))
        print("数字{}, 子进程id>>{}, 父进程id>>{}".format(n,os.getpid(),os.getppid()))
    if __name__ == '__main__':
        for i in range(1,11):
            Process(target=func,args=(i,)).start()
        print("主进程执行结束了...")
        print(os.getpid())

    六、join

    """
    join 等待当前子进程全部执行完毕之后,
    主进程在执行(用来同步子父进程的)
    """

    1、join的基本用法

    def func():
        print("发送第一封邮箱,要求张工资")
        
    if __name__ == "__main__":
        p = Process(target=func)
        p.start()
        
        # 必须等待子进程全部执行结束之后,在执行主进程中的代码,用join来同步子父进程.
        p.join()
        # time.sleep(1)
        print("发送第二封邮箱,涨到一个月6万")

    2、多个子进程的场景使用join

    if __name__ == "__main__":
        lst = []
        for i in range(10):
            p = Process(target=func, args=(i,))
            p.start()
            lst.append(p)
    
        # 所有子进程都执行完,执行主进程
        for i in lst:
            i.join()
    
        print("主进程发最后一封邮件:此致敬礼~")

    七、自定义进程类

    """
    自定义进程类的要求:
    (1) 必须继承Process这个父类
    (2) 所有进程执行任务的逻辑必须写在run方法里面
    """

    1、基本语法

    class MyProcess(Process):
        def run(self):
            print("1.子进程id>>{},2父进程id>>{}".format(os.getpid(), os.getppid()))
    
    
    if __name__ == "__main__":
        p = MyProcess()
        p.start()
        print("3.子进程id>>{},4父进程id>>{}".format(os.getpid(), os.getppid()))

    2、带有参数自定义类的方法

    class MyProcess(Process):
        def __init__(self, arg):
            # 手动调用一下父类的构造方法(最终实现进程的创建)
            # 用self就永远找自己了
            super().__init__()
            self.arg = arg
    
        def run(self):
            print("1.子进程id>>{},2父进程id>>{}".format(os.getpid(), os.getppid()))
            print(self.arg)
    
    
    if __name__ == "__main__":
        p = MyProcess("我是传进来的参数")
        p.start()
        print("3.子进程id>>{},4父进程id>>{}".format(os.getpid(), os.getppid()))

    八、守护进程

    """
    守护进程守护的是主进程,如果主进程中的所有代码执行完毕了,
    当前这个守护进程会被立刻杀死,立刻终止.
    语法:
    进程.daemon = True 设置当前这个进程为守护进程
    必须写在start()调用进程之前进行设置
    
    
    默认:主进程会默认等待所有子进程执行结束之后,在关闭程序,释放资源
    """

    1、基本使用

    from multiprocessing import Process
    import time
    def func():
        print("start当前子进程")
        time.sleep(1)
        print("end当前子进程")
    
    
    if __name__ == "__main__":
        p = Process(target=func)
        p.daemon = True
        p.start()
    
        print("主进程执行结束 ... ")

    2、多个子进程的场景

    from multiprocessing import Process
    import time
    def func1():
        count = 1
        while True:
            print("*" * count)
            time.sleep(0.5)
            count += 1
    
    
    def func2():
        print("start func2 当前子进程任务")
        time.sleep(3)
        print("end   func2 当前子进程任务")
    
    
    if __name__ == "__main__":
        p1 = Process(target=func1)
        p2 = Process(target=func2)
    
        # 设置p1这个进程对象为守护进程
        p1.daemon = True
    
        p1.start()
        p2.start()
    
        time.sleep(1)
    
        # 主进程结束 p1守护进程结束
        print("主进程执行结束 ... ")

    3、守护进程实际用途:监控报活(报告存活)

    from multiprocessing import Process
    import time
    def alive():
        while True:
            print("给监控的总服务器发消息,报告自己的存活状态, i am alive~")
            time.sleep(1)
    
    
    # 执行任务
    def func():
        while True:
            try:
                time.sleep(1)
                raise RuntimeError
                print("当前5号服务器功能:对日志进行数据分析.... ")
            except:
                break
        # pass
    
    
    if __name__ == "__main__":
        # 创建2个子进程
        p1 = Process(target=alive)
        p2 = Process(target=func)
        # 设置p1为守护进程
        p1.daemon = True
    
        p1.start()
        p2.start()
    
        # 必须等到p2任务执行结束之后,在向下执行.
        p2.join()
    
        print("当前服务器状态异常 ... ")

  • 相关阅读:
    判断广播是否已注册
    Android 之使用LocalBroadcastManager解决BroadcastReceiver安全问题
    Android BroadcastReceiver 注册和反注册
    关于Android TaskAffinity的那些事儿
    文件读取方法(FileHelpers) z
    FileHelpers 用法 z
    tdf sample
    打开文件
    async/await 异步编程
    使用Topshelf创建Windows服务
  • 原文地址:https://www.cnblogs.com/kongxiangqun/p/13520325.html
Copyright © 2020-2023  润新知