zoukankan      html  css  js  c++  java
  • Python Day 32 进程和程序的区别、阻塞 非阻塞 并行 并发、进程的三种状态、进程的创建和销毁、python中两种方式实现多进程、进程间内存相互隔离、join函数孤儿进程与僵尸进程

      ##内容回顾

    # UDP协议  
    
    ​    用户数据报协议,是OSI模型中属于传输层的协议 
    
    ​    提供,不可靠的,不要求顺序的,数据量小的,速度快的传输服务 
    
    ​    不可靠:
    
    ​        发送完成后不需要确认信息 并且立即删除缓存中的数据 
    
    ​    不要求顺序:
    
    ​        当一个数据较大时 会分为多个数据报来传输,对方无法获知数据的顺序,以及是否完整
    
    ​    数据量较小的:
    
    ​        数据越大丢包的可能性越高 ,建议的数据量不要超过1472
    
    ​    速度快:
    
    ​        相对于TCP而言快很多 不需要确认信息 ,也不需要建立链接 
    
    # 通讯流程
    
    ​    如果TCP比喻为手机打电话的过程 那么UDP可以看做是对讲机   
    
    ​    1.买机器    创建UDP的socket 
    
    ​    2.固定频道    bind一个ip和端口
    
    ​    3.收发数据      recvfrom   sendto 
    
    ​    
    
    ​    接收
    
    ​    1.买机器    创建UDP的socket 
    
    ​    2.收发数据      recvfrom   sendto 
    
    ​        注意 不能先收    要收数据 必须明确端口号  没有端口号是不可能使用网络服务的 
    
    
    
    ​    
    
    ###TCP  与 UDP 的其他区别
    
    1.没有连接  
    
    2.不会粘包     每次发送都是一个独立的数据包    
    
    
    
    TCP 对数据完整性要求较高 : 在线支付  ,文字信息 
    
     UDP: 对数据不要求完整性 但是要快 :  视频 语音 游戏  
    
    # DNS 
    
    域名解析服务器  
    
    域名 就是一串有规律的字符串  ,用于绑定IP,目的是为了方便记忆 
    
    域名解析服务器    就是帮你将域名转换为ip地址  
    
    本质就是一个数据库  里面存的就是域名和ip对应关系   
    
    一台机器性能有限
    
    分为 
    
    ​    根域名服务器        只存储定义域名服务器的信息  
    
    ​    顶级域名服务器 只存储二级域名服务器的信息  
    
    ​    二级域名服务器    二级存三级 
    
    ​    三级域名   三级可以存四级  通常直接存储具体的ip信息  
    
    ​    .....................
    
    ​    本地DNS  用于加速解析    
    
    
    
    ###自己搭建DNS 的作用
    1.CDN     内容分发网络       就是在你的周围建立更多镜像服务    
    
    ​    2.集群   
    
    # 操作系统
    
    也是一个软件, 
    
    ​    受保护的不能随意修改  
    
    ​    代码量巨大  内核在500万以上 
    
    ​    长寿 ,一旦完成一般不改 
    
    ​    linux是脱袜子  将(shell 保留解释权!)  移植到minux上 结合产生的 
    
    ###操作系统的作用:
    
    1.将复杂丑陋的硬件细节隐藏起来,提供了简单的调用接口 
    
    2.将应用程序对于硬件的竞争变的有序  
    
    
    
    ###操作系统发展史  
    1.第一带计算机   真空管和穿孔卡片  没有进程 没有操作系统   
    
    ​    2.第二代计算机  7094 1401    晶体管  批处理系统 
    
    ​        输入输出  以及计算设备 不能互联  需要人参与    一批一批的处理   开发效率慢  并且串行执行
    
    ​    3.第三代计算机    集成电路 与多道技术 
    
    ​        多终端联机  spooling      同一台机器既能进行科学计算  又能做字符处理       通用计算机
    
    ​        多道技术   解决串行导致的效率低下问题
    
    ​        多用户终端    可以同时为多个用户提供服务  每个用户以为自己独享一台计算机   
    
    ​    4.第四代   个人电脑
    
    ​        大规模使用了集成电路,大多都提供了GUI界面  
    
    # 多道技术   
    
    ​    产生背景 ,所有程序串行 导致资源浪费   
    
    ​    目的是让多个程序可以并发执行  , 同时处理多个任务   
    
    ## 关键技术
    
    ### 空间复用
    
    指的是 同一时间 内存中加载多个不同程序数据,
    
    每个进程间内存区域相互隔离,物理层面的隔离  
    
    ### 时间复用       切换 + 保存
    
        # 切换条件:
    
        1.一个进程执行过程中遇到了IO操作  切换到其他进程
    
        2.运行时间过长,会被操作系统强行剥夺执行权力   
    
    单纯的切换不够,必须在切换前保存当前的状态,以便于恢复执行  
    
    
    
    # 进程
    
    一个正在被运行的程序就称之为进程,是程序具体执行过程,一种抽象概念
    
    进程来自于操作系统  

      ##多进程

    # 进程和程序的区别  
    “”“
    
    程序就是一堆计算机可以识别文件,程序在没有被运行就是躺在硬盘上的一堆二进制
    
    运行程序时,要从硬盘读取数据到内存中,CPU从内存读取指令并执行 ,
    
    一旦运行就产生了进程    
    
    一个程序可以多次执行 产生多个进程,但是进程之间相互独立
    
    当我们右键运行了一个py文件时 ,其实启动的是python解释器,你的py文件其实是当作参数传给了解释器   
    
    ”“”
    
    # 阻塞  非阻塞   并行  并发   (重点)
    “”“
    #1、阻塞与非阻塞指的是程序的两种运行状态
    # 阻塞:遇到IO就发生阻塞,程序一旦遇到阻塞操作就会停在原地,并且立刻释放CPU资源
      本地IO input      print     sleep    read  write      

    ​    网络IO recv  send

    # 非阻塞(就绪态或运行态):没有遇到IO操作,或者通过某种手段让程序即便是遇到IO操作也不会停在原地,执行其他操作,力求尽可能多
    并发: 多个任务看起来同时在处理 ,本质上是切换执行 速度非常快 并行: 多个任务真正的同时执行 必须具备多核CPU 才可能并行 并发 并行 说的是 任务的处理方式 ”“”

      ##进程的三种状态

    #就绪态,运行态,和阻塞态
    
    多道技术会在进程执行时间过长或遇到IO时自动切换其他进程,意味着IO操作与进程被剥夺CPU执行权都会造成进程无法继续执行

      ##程序员的永恒话题

    提高效率
    
    根本方法就是让程序尽可能处于运行状态
    
    减少IO  尽可能多占用CPU时间     
    
    缓冲区就是用于减少IO操作的

      ##进程的创建和销毁(了解)

    ### 进程的创建
    
    但凡是硬件,都需要有操作系统去管理,只要有操作系统,就有进程的概念,就需要有创建进程的方式,一些操作系统只为一个应用程序设计,比如微波炉中的控制器,一旦启动微波炉,进程就已经存在。
    
      而对于通用系统(跑很多应用程序),需要有系统运行过程中创建或撤销进程的能力,主要分为4中形式创建新的进程
    
    1. 系统初始化(查看进程linux中用ps命令,windows中用任务管理器,前台进程负责与用户交互,后台运行的进程与用户无关,运行在后台并且只在需要时才唤醒的进程,称为守护进程,如电子邮件、web页面、新闻、打印)
    2. 一个进程在运行过程中开启了子进程(如nginx开启多进程,os.fork,subprocess.Popen等)
    3. 用户的交互式请求,而创建一个新进程(如用户双击暴风影音)
    4. 一个批处理作业的初始化(只在大型机的批处理系统中应用)
    
    ### 进程的销毁
    
    1. 正常退出(自愿,如用户点击交互式页面的叉号,或程序执行完毕调用发起系统调用正常退出,在linux中用exit,在windows中用ExitProcess)
    2. 出错退出(自愿,python a.py中a.py不存在)
    3. 严重错误(非自愿,执行非法指令,如引用不存在的内存,1/0等,可以捕捉异常,try...except...)
    4. 被其他进程杀死(非自愿,如kill -9### 进程的层次结构
    
    无论UNIX还是windows,进程只有一个父进程,不同的是:
    
    1. 在UNIX中所有的进程,都是以init进程为根,组成树形结构。父子进程共同组成一个进程组,这样,当从键盘发出一个信号时,该信号被送给当前与键盘相关的进程组中的所有成员。
    2. 在windows中,没有进程层次的概念,所有的进程都是地位相同的,唯一类似于进程层次的暗示,是在创建进程时,父进程得到一个特别的令牌(**称为句柄**),该句柄可以用来控制子进程,但是父进程有权把该句柄传给其他子进程,这样就没有层次了。

      ##python中实现多进程

    “”“
    在一个应用程序中可能会有多个任务需要并发执行,但是对于操作系统而言,一个进程就是一个任务,CPU会从上往下依次执行代码,当代码中遇到IO操作时,操作系统就会剥夺CPU执行权给其他应用程序,这样对于当前应用程序而言,效率就降低了,如何使得程序既能完成任务又不降低效率呢?答案就是让把当前程序中的耗时操作交給子进程来完成,如此当前应用程序可以继续执行其他任务!
    ”“”
    
    #python中开启子进程的两种方式
    
    #方式一:直接实例化Process  ,将要执行任务用target传入
    from multiprocessing import Process
    import os
    import time
    # 为什么要子进程   当出现一些耗时较长的操作时 会导致程序进入阻塞状态  二无法执行其他代码
    # 这时候就可以开启子进程把任务交给他
    
    def task(name):
        print(" name %s 子进程run!" % name)
        # print("son is :%s" % os.getpid())
        # print("father is :%s" % os.getppid())
        time.sleep(3)
        print("子进程 over!")
    
    
    if __name__ == '__main__':
        print("father :%s" % os.getpid())
        p = Process(target=task,args=("rose",))
        p.start() # 开启子进程   本质是向操作系统发送请求 让它启动进程    通常不可能立即开启
        print("任务结束!")
    
    """
    windows  和  linux 开启进程的方式不同 
    首先相同之处都是 需要将数据copy一份给子进程   这样子进程才知道要干什么  
    linux 会将父进程的所有数据 完全copy    
    windows  会copy 一部分数据   同时会导入py文件来执行   这样一来递归开进程    
    linux 拿到父进程知道代码位置 继续执行   
    建议都加上判断  可以保证两个平台都能用  
    
    记住:
    开启进程的代码 都把它放到  if __name__ == "__main__": 中即可
    
    
    """
    
    
    #方式二:继承Process类 ,覆盖run方法  将任务放入run方法中 (重点掌握) 
    import os
    from multiprocessing import  Process
    class MyProcess(Process):
        def __init__(self,name):
            super().__init__()
            self.name = name
        # 继承Procee覆盖run方法将要执行任务发到run中
        def run(self):
            print(self.name)
            print("子进程 %s running!" % os.getpid())
            print("子进程 %s over!" % os.getpid())
    
    if __name__ == '__main__':
        # 创建时 不用再指定target参数了
        p = MyProcess("rose")
        p.start()
        print("父进程over!")

      ##进程间内存相互隔离

    from multiprocessing import Process
    import time
    name = "青椒"
    def task():
        global name
        name = "rose"
        print("改完了!")
        print("子进程的%s" % name)
    
    
    if __name__ == '__main__':
        p = Process(target=task)
        p.start()
        time.sleep(2)
        print(name)

      ##join函数

    “”“
    调用start函数后的操作就由操作系统来玩了,至于何时开启进程,进程何时执行,何时结束都与应用程序无关,所以当前进程会继续往下执行,join函数就可以是父进程等待子进程结束后继续执行,即用于提高子进程优先级 ,使得父进程等待子进程结束  
    ”“”
    
    #案例
    """
        当你开启了一个子进程 并且给他一个任务  如果你希望知道这个任务什么时候完成 那就需要等待
    
    """
    import time,os
    from multiprocessing import Process
    # def task(i):
    #     # print(" %s 买烟去了" % i)
    #     time.sleep(3)
    #     print("%s 买完了!" % i)
    #
    # if __name__ == '__main__':
    #     # p = Process(target=task)
    #     # p.start()
    #     # # time.sleep(5)
    #     # p.join() # 等待子进程执行完毕   将子进程的优先级提高
    #     #
    #
    #
    #
    #     for i in range(10):
    #         p = Process(target=task,args=(i,))
    #         p.start()  # 进程启动顺序  与start无关   主要看操作系统先切换谁
    #         # p.join()
    #
    #     p.join()  # 最后一个
    #
    #
    #     print("over!")
    
    
    def task(i):
        # print(" %s 买烟去了" % i)
        time.sleep(i)
        print("%s 买完了!" % i)
    
    if __name__ == '__main__':
        strat_time = time.time()
        p1 = Process(target=task,args=(1,))
        p2 = Process(target=task,args=(2,))
        p3 = Process(target=task,args=(3,))
    
        p1.start()
        p2.start()
        p3.start()
    
        p3.join() #3
        p2.join()
        p1.join()
    
    
        end_time = time.time()
        print(end_time - strat_time)
        print("over!")


    #案例2
    from multiprocessing import Process
    import time,random
    x=1000
    def task(n):
        print('%s is runing' %n)
        time.sleep(n)
    if __name__ == '__main__':
        start_time=time.time()
        p1=Process(target=task,args=(1,))
        p2=Process(target=task,args=(2,))
        p3=Process(target=task,args=(3,))
        p1.start()
        p2.start()
        p3.start()
        p3.join() #3s
        p1.join()
        p2.join()
        print('主',(time.time() - start_time))
        start_time=time.time()
        p_l=[]
        for i in range(1,4):
            p=Process(target=task,args=(i,))
            p_l.append(p)
            p.start()
        for p in p_l:
            p.join()
       
        print('主',(time.time() - start_time))

      ##Process对象常用属性

    from multiprocessing import  Process
    import time,os
    def task():
        print("121121")
        # time.sleep(10)
        # print("over")
        # print(os.getppid())
        exit(1000)
    
    if __name__ == '__main__':
        p = Process(target=task,name="rose")
        p.start() # 懒加载优化机制  如果没有调用start 那么该对象将不会被创建
        time.sleep(1)
        # p.join() # 等待子进程结束
        # p.terminate()  # 终止进程
        # print(p.name)  # 进程的名称
        # print(p.is_alive()) #是否存活
        # p.terminate() # 与start一样 都是给操作系统发送指令 所以会有延迟
        # print(p.is_alive())
        # print(p.pid)
        # print(p.exitcode) # 获取退出码

      ##孤儿进程与僵尸进程

    ## 孤儿进程
    
    指的是,父进程先结束 ,而子进程还在运行着, 
    
    孤儿进程无害,有 其存在的必要性 
    
    例如:qq开启了浏览器,qq先退出了  浏览器应该继续运行  
    
    孤儿进程会被操作系统接管    
    
    
    
    ## 僵尸进程
    
    值得是,子进程已经结束了,但是操作系统会保存一些进程信息,如PID,运行时间等,此时这个进程就称之为僵尸进程  
    
    僵尸进程如果太多将会占用大量的资源,造成系统无法开启新新进程 
    
    linux 中有一个wai/waitpid 用于父进程回收子进程资源
    
    python会自动回收僵尸进程  

      

  • 相关阅读:
    oracleI基础入门(6)sql语句Substring Crazy
    oracleI基础入门(7)table约束 Crazy
    oracleI基础入门(7)table视图 Crazy
    SQL附加分离数据库(命令)
    双截棍 C语言版 (超搞笑)
    AspNetPage分页(repeater),自己做的例子基本代码
    记录
    RegularExpressionValidator控件中正则表达式用法
    20 个经典的 Ajax + CSS 表格
    GridView各个事件中,怎样获取主键值
  • 原文地址:https://www.cnblogs.com/liangzhenghong/p/10956994.html
Copyright © 2011-2022 走看看