zoukankan      html  css  js  c++  java
  • 第二十八天:进程

    操作系统发展史

    穿孔卡片

    一个机房只能用一个卡带,一次只能被一个人使用

    缺点:cpu利用率极低

    联机批处理

    支持多用户去使用一个机房

    脱机批处理

    高速磁盘:提高了处理速度

    优点:提高了使用率

    多道技术

    单道:

    使用是串行,基于单核cpu,一次只能执行一个软件,一个程序结束之后才能执行下一个程序

    多道

    cpu执行的同时,去加载其他的程序

    空间上的复用:一个cpu可以提供给多个程序使用,公用内存条一个,每个进程都有各自独立的内存空间,互不干扰,物理级别的隔离d

    时间上的复用:切换+保存状态

    切换:若cpu遇到I/O操作,会立即将当前执行的程序cpu使用权断开切换给其他用户

    提高了cpu的使用率

    若一个cpu程序的使用时间过长,会立即将切换使用权

    导致程序的执行率降低。

    保存状态:当再次回到本程序的执行时,不需要重新加载

    并发与并行

    并发:

    指的是看起来像在同时运行

    相当于多个程序不不停的切换+保存状态

    并行:

    指的是真正意义上的同时运行

    基于多核,同时执行多个程序

    进程

    程序:指的是一堆代码

    进程:指的是一堆代码运行的过程

    进程调度

    1. 先来先服务

      若a程序先来,则先占用cpu

      缺点:必须程序B必须等待A使用完cpu后才能使用

    2. 短作业优先

      谁的用时短,谁优先使用cpu

      缺点:若程序A使用时间最长,后面还有N个运行时间短的程序,则A要等所有程序结束后才执行

    3. 时间轮转

      在一秒种,加载了N个用户,要将一秒等分位N个时间片

    4. 分级反馈队列

      将执行优先分为多个级别。

      越往下的优先级越低

      程序运行时的三种状态

      就绪

      所有进程创建时都会进入就绪态

      运行

      程序调度后,进入运行态

      阻塞

      凡是遇到I/O操作的进程都会进入阻塞态,若I/O结束,必须重新进入就绪态

      同步和异步

      指的时提交任务的方式。

      同步

      若有两个任务需要提交,在提交第个任务时,必须等待该任务执行结束后,才能继续提交并执行第二个任务

      异步

      若有两个任务提交,在提交第一个任务时没不需要原地等待,立即可以执行第二个任务

      阻塞和非阻塞

      阻塞

      阻塞态。遇到I/O一定会阻塞

      非阻塞

      就绪态

      运行态

      同步和异步,阻塞和非阻塞是同一个概念吗?

      不是,不能混为一谈!

      想要cpu利用率最大化,需要异步提交,和非阻塞态。但是一个程序基本上都会有I/O操作,所以只能尽可能减少不必要的I/O操作

    创建进程的 两种方式

    定义一个任务

    def task(name):
        print(f'{name}开始执行')
        time.sleep(1)
        print(f'{name}的任务已经结束')
    
    # 在windows下这里必须使用这种形式运行,不然会报错
    if __name__ == '__main__':
        p = Process(target=task, args=('lk',))
        p.start()
        print('主进程')
    
    

    定义一个类,并继承Process

    # 自定义个类,并继承Process
    class MyProcess(Process):
    
        def run(self):
            print('开始执行子进程')
            time.sleep(1)
            print('任务结束子进程')
    
    
    if __name__ == '__main__':
        p = MyProcess()
        p.start()
        print('主进程结束')
    

    join方法

    让子进程结束后再结束父进程

    join方法要写在start的下面,因为start的作用是开启一个子进程

    def task(name):
        print(f'{name}开始执行')
        time.sleep(1)
        print(f'{name}的任务已经结束')
    
    # 在windows下这里必须使用这种形式运行,不然会报错
    if __name__ == '__main__':
        p = Process(target=task, args=('lk',))
        p.start()
        p.join()
        print('主进程结束')
        
    
    

    进程之间数据是相互隔离的

    from multiprocessing import Process
    x = 100
    
    def func():
        global  x
        x = 200
    
    if __name__ == '__main__':
        p = Process(target=func)
        p.start()
        print(x)
        print('主进程')
    
    

    进程的属性关系

    current_process().pid:获取子进程号

    os.getpid():获取主进程号

    os.ppid()获取主主进程进程号

    进程号都是随机分配的

    cmd中查看进程:tasklist |finddstr 进程号

    进程号回收的两种条件

    1. join可以回收子进程与主进程
    2. 之进程正常结束,子进程和主进程也会被正常回收

    .is_alive()判断子进程是否存活,返回布尔值

    .terminate()直接告诉操作系统,杀掉子进程

    僵尸进程与孤儿进程

    僵尸进程

    指的是子进程已经结束,但是PID号还是存在,未被销毁

    缺点:占用PID号,占用操作系统资源

    孤儿进程

    指的是子进程还在实行,但父进程意外结束。

    操作系统提供一个福利院,帮你回收没有父进程的子进程。

    守护进程

    指的是主进程结束后,该进程产生的所有子进程都跟着结束,并回收

    .deamon()

  • 相关阅读:
    Deep Learning 15:RBM的学习
    [解惑]MHA基本原理
    里程碑--学会蝶泳
    orchestrator中的raft snapshot操作
    使用binlog恢复被删除的数据
    关于MySQL binlog二进制日志
    无锁加载配置
    go tool trace 浏览器空白页问题 trace shows blank page
    godoc的使用
    Error 1390: Prepared statement contains too many placeholders
  • 原文地址:https://www.cnblogs.com/lyyblog0715/p/11716156.html
Copyright © 2011-2022 走看看