zoukankan      html  css  js  c++  java
  • multiprocess模块

    什么是进程

    什么是进程

    进程是计算机中的程序关于某数据集合一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础,进程与进程之间数据隔离,执行过程异步

    为什么会出现进程的概念

    合理利用cpu,提高客户体验,多个进程是可以利用多个cpu的,可以实现并行的效果

    进程的特征

    动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
    并发性:任何进程都可以同其他进程一起并发执行
    独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
    异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
    结构特征:进程由程序、数据和进程控制块三部分组成。
    多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。

    进程与程序的区别

    程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。
    而进程是程序在处理机上的一次执行过程,它是一个动态的概念。
    程序可以作为一种软件资料长期存在,而进程是有一定生命期的。
    程序是永久的,进程是暂时的。

    进程的调度

    要想多个进程交替运行,操作系统必须对这些进程进行调度,这个调度也不是随即进行的,而是需要遵循一定的法则,由此就有了进程的调度算法

    先来先服务调度算法

    先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。FCFS算法比较有利于长作业(进程),而不利于短作业(进程)。
    由此可知,本算法适合于CPU繁忙型作业,而不利于I/O繁忙型的作业(进程)。

    短作业优先调度算法

    短作业(进程)优先调度算法(SJ/PF)是指对短作业或短进程优先调度的算法,该算法既可用于作业调度,也可用于进程调度。
    但其对长作业不利;不能保证紧迫性作业(进程)被及时处理;作业的长短只是被估算出来的。

    时间片轮转法

    View Code

    多级反馈队列

    View Code

    multiprocess.process模块

    process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建

    Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)
    
    强调:
    1. 需要使用关键字的方式来指定参数
    2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
    
    参数介绍:
    group参数未使用,值始终为None
    target表示调用对象,即子进程要执行的任务
    args表示调用对象的位置参数元组,args=(1,2,'egon',)
    kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
    name为子进程的名称

     

    import os
    from multiprocessing import Process
    def son_process():
        '''这个函数中的代码是在子进程中执行的
            getpid():查看当前进程的ID
            getppod():查看父进程的ID
            '''
        print('执行我了',os.getpid(),os.getppid())
    if __name__ == '__main__': #此句话在mac或linux中不必写
        #son_process 的外面是一个主进程
        print('父进程',os.getpid())
        p = Process(target=son_process) #target:表示调用对象,即进程要执行的任务
        p.start() #启动进程,并调用改子进程中的p.run()
    
    结果:
    父进程 10020
    执行我了 10416 10020

    方法介绍

    1. p.start():启动进程,并调用该子进程中的p.run() 
    2. p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法  
    3  p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
    4  p.is_alive():如果p仍然运行,返回True
    5  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. p.name:进程的名称
    3. p.pid:进程的pid
    4. p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
    5. p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)

    在windows中使用process模块的注意事项

    View Code

    进程

    开启一个子进程

     1.开启了一个子进程就已经实现了并发: 父进程(主进程)和子进程并发(同时执行)
    def son_process():
        print('son start')
        time.sleep(1)
        print('son end')
    
    if __name__ == '__main__':
        p = Process(target=son_process)
        p.start()
        for i in range(5):
            print('主进程')
            time.sleep(0.3)

    开启多个子进程

    def son_process():
        print('son start')
        time.sleep(1)
        print('son end')
    
    if __name__ == '__main__':
        for i in range(3):
            p = Process(target=son_process)

    给子进程中传参数

    def son_process(i):
        print('son start',i)
        time.sleep(1)
        print('son end',i)
    
    if __name__ == '__main__':
        for i in range(10):
            p = Process(target=son_process,args=(i,))
            p.start()  # 通知操作系统 start并不意味着子进程已经开始了

    主进程和子进程之间的关系

    def son_process(i):
        print('son start',i)
        time.sleep(1)
        print('son end',i)
    
    if __name__ == '__main__':
        for i in range(10):
            p = Process(target=son_process,args=(i,))
            p.start()
        print('主进程的代码执行完毕')
    # 主进程会等待子进程结束之后才结束
    # 为什么?
    # 父进程负责创建子进程,也负责回收子进程的资源

    主进程直接结束一个子进程

    def son_process(i):
        while True:
            print('son start',i)
            time.sleep(0.5)
            print('son end',i)
    
    if __name__ == '__main__':
        p = Process(target=son_process, args=(1,))
        p.start()           # 开启一个子进程,异步的
        print('主进程的代码执行完毕')
        print(p.is_alive())  # 子进程还活着
        p.terminate()        # 结束一个子进程,异步的
        print(p.is_alive())  # 子进程还在活着
        time.sleep(0.1)
        print(p.is_alive())

    开启十个进程执行

    # 主进程里的print('主进程n : ',n)这句话在十个子进程执行完毕之后才执行
    n = [100]
    import random
    def sub_n():
        global n  # 子进程对于主进程中的全局变量的修改是不生效的
        time.sleep(random.random())
        n.append(1)
        print('子进程n : ',n)
    if __name__ == '__main__':
        p_lst = []
        for i in range(10):
            p = Process(target = sub_n)
            p.start()
            p_lst.append(p)
        for p in p_lst:p.join()  # 阻塞 只有一个条件是能够让我继续执行 这个条件就是子进程结束
        print('主进程n : ',n)

    join的扩展

    n = [100]
    def sub_n():
        global n  # 子进程对于主进程中的全局变量的修改是不生效的
        n.append(1)
        print('子进程n : ',n)
        time.sleep(10)
        print('子进程结束')
    
    if __name__ == '__main__':
        p = Process(target = sub_n)
        p.start()
        p.join(timeout = 5)     # 如果不设置超时时间 join会阻塞直到子进程p结束
        # timeout超时
        # 如果设置的超时时间,那么意味着如果不足5s子进程结束了,程序结束阻塞
        # 如果超过5s还没有结束,那么也结束阻塞
        print('主进程n : ',n)
        p.terminate()  # 也可以强制结束一个子进程

    守护主进程

    import time
    from multiprocessing import Process
    def alive():
        while True:
            print('连接监控程序,并且发送报活信息')
            time.sleep(1)
    def func():
        '''主进程中的核心代码'''
        while True:
            print('选择的项目')
            time.sleep(1)
            print('选择后做的事情')
            time.sleep(0.2)
    if __name__ == '__main__':
        p = Process(target = alive)
        p.daemon = True #设置子程序为守护程勋,守护进程会随着主进程代码的接结束而结束
        p.start()
        func()

    设置子进程为守护进程,守护进程会随着主进程代码的结束而结束,由于主进程要负责给所有的子进程收尸,所有主进程必须是最后结束,守护进程只能在主进程大代码结束之后就认为主进程结束了,守护进程在主进程的代码结束之后就结束了,不会等待其他子进程结束

    守护其他进程

    import time
    from multiprocessing import Process
    def alive():
        while True:
            print('连接监控程序,并且发送报活信息')
            time.sleep(1)
    def func():
        '''主进程中的核心代码'''
        while True:
            print('选择的项目')
            time.sleep(1)
            print('选择后做的事情')
            time.sleep(0.2)
    if __name__ == '__main__':
        p = Process(target = alive)
        p.daemon = True #设置子程序为守护程勋,守护进程会随着主进程代码的接结束而结束
        p.start()
        p = Process(target=func)
        p.start()
        p.join() # 在主进程中等待子进程结束,守护进程就可以帮助守护其他子进程了
  • 相关阅读:
    【slenium专题】Webdriver同步设置
    【Selenium专题】WebDriver启动firefox浏览器
    【Selenium专题】WebDriver启动Chrome浏览器(二)
    【Selenium专题】WebDriver启动Chrome浏览器(一)
    Jenkins邮件设置
    Jenkins安装笔记
    for循环输出i为同一值的问题,SetTimeOut
    const、let、var的区别
    浏览器title失去焦点时改变title
    clone对象或数组
  • 原文地址:https://www.cnblogs.com/wanglan/p/10083741.html
Copyright © 2011-2022 走看看