操作系统发展、同步异步阻塞非阻塞、进程

目录

  • 操作系统发展史
    • 穿孔卡片
    • 联机批处理
    • 脱机批处理系统
    • 多道技术(基于单核情况下研究)
    • 并发与并行
  • 进程
    • 程序与进程:
    • 进程调度:
  • 同步异步阻塞非阻塞
    • 进程的三个状态:
    • 同步与异步
    • 阻塞与非阻塞
  • 创建进程
    • 进程的创建
    • 创建子进程两种方式
  • join方法的使用
  • 进程间数据是相互隔离的
  • 进程对象的属性
  • 僵尸进程和孤儿进程(了解)
    • 僵尸进程
    • 孤儿进程
  • 守护进程

操作系统发展史

穿孔卡片

一个计算机房,只能被一个穿孔卡片使用

缺点:

  • CPU利用率低

联机批处理

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

脱机批处理系统

高速磁盘:

  • 提高文件的读取速度

优点:

  • 提高CPU的利用率

多道技术(基于单核情况下研究)

  • 单道:多个使用CPU是串行
  • 多道:
    • 空间上的复用:一个CPU可以提供给多个用户去使用
    • 时间上的复用:切换 + 保存状态

时间上复用说明:

(1)若CPU遇到IO操作,会立即将当前执行程序CPU使用权断开
优点:CPU的利用率高

(2)若一个程序使用CPU的时间过长,会立即将当前执行程序CPU使用权断开

缺点:程序的执行率降低

并发与并行

并发:指的是看起来像同时运行,多个程序不停地切换 + 保存状态

并行:真实意义上的同时运行

进程

程序与进程:

  • 程序:一堆代码
  • 进程:一堆代码运行的过程

进程调度:

当代操作系统使用的是:时间片轮转法 + 分级反馈队列

  1. 先来先服务调度:

    a, b程序, 若a程序先来, 先占用CPU

    缺点:程序a先使用,程序b必须等待程序a使用CPU结束后才能使用

  2. 短作业优先调度:

    a, b程序,谁的用时短,先优先调度使用cpu

    缺点:若程序a使用时间最长,有N个程序使用时间短,必须等待所有用时短的程序结束后才能使用

  3. 时间片轮转法

    CPU执行的时间1秒中,加载N个程序。要将1秒钟等分N个时间片

  4. 分级反馈队列
    将执行优先分为多层级别

同步异步阻塞非阻塞

进程的三个状态:

  • 就绪态:所有程序创建时都会进入就绪态,准备调度
  • 运行态:调度后的进程,进入运行态
  • 阻塞态:凡是遇到IO操作的进程,都会进入阻塞态;若IO结束必须重新进入就绪态

操作系统发展、同步异步阻塞非阻塞、进程_第1张图片

同步与异步

指的是提交任务的方式

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

  • 异步:若有两个任务需要提交,在提交第一个任务时,不需要原地等待,立即可以提交并执行第二个任务。

阻塞与非阻塞

  • 阻塞:遇到IO一定会阻塞
  • 非阻塞:指的是就绪态、运行态

最大化提高CPU的使用率:

尽可能减少不必要的IO操作

创建进程

进程的创建

windows中创建子进程,会将当前父进程代码重新加载执行一次

在Linux/mac中,会将当前父进程重新拷贝一份,再去执行

创建子进程两种方式

from multiprocessing import Process
import time

# 定义一个任务
def task(name):
    print(f'{name}的任务开始执行')
    time.sleep(1)
    print(f'{name}的任务已经结束')


if __name__ == '__main__':
    p = Process(target=task, args=('cwz',))
    p.start()
    print('主进程')
    
'''
主进程
cwz的任务开始执行
cwz的任务已经结束
'''

# 自定义一个类,并继承Process
class MyProcess(Process):

    # 父类方法
    def run(self):
        print('开始执行任务')
        time.sleep(1)
        print('结束执行任务')

if __name__ == '__main__':
    p = MyProcess()
    p.start()
    print('主进程')

'''
主进程
开始执行任务
结束执行任务
'''

join方法的使用

用来告诉操作系统,让子进程结束后再结束父进程

from multiprocessing import Process
import time

def task(name):
    print(f'{name} start...')
    time.sleep(2)
    print(f'{name} over...')


if __name__ == '__main__':
    p = Process(target=task, args=('neo', ))
    p.start()   # 告诉操作系统,开启子进程
    p.join()    # 告诉操作系统,结束子进程后,父进程再结束
    print('主进程')
    
    
'''
neo start...
neo over...
主进程
'''

进程间数据是相互隔离的

from multiprocessing import Process
import time

x = 100
def func():
    print('执行func函数')
    global x
    x = 200


if __name__ == '__main__':
    p = Process(target=func)
    p.start()
    print(x)   # 不能修改x的值
    print('主进程')
    
    
'''
100
主进程
执行func函数
'''

进程间数据相互隔离:
主进程与子进程间会有各自的名称空间

进程对象的属性

  • p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
  • p.name:进程的名称
  • p.pid:进程的pid
  • p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
  • p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层
from multiprocessing import Process
from multiprocessing import current_process
import time
import os

def task(name):
    # current_process().pid 获取子进程号
    print(f'{name} start...', current_process().pid)
    time.sleep(2)
    print(f'{name} over...', current_process().pid)


if __name__ == '__main__':
    p = Process(target=task, args=('neo', ))
    p.start()
    print('主进程', os.getpid())
    print('主主进程', os.getppid())


'''
主进程 12576
主主进程 12476
neo start... 7772
neo over... 7772
'''

进程号回收的两种条件:

  • join, 可以回收子进程与主进程
  • 主进程正常结束,子进程与主进程也会回收

主进程这里指的是python解释器

主主进程指的是pycharm

p.is_alive 可以查看子进程存活状态

from multiprocessing import Process
from multiprocessing import current_process
import time
import os

def task(name):
    # current_process().pid 获取子进程号
    print(f'{name} start...', current_process().pid)
    time.sleep(2)
    print(f'{name} over...', current_process().pid)


if __name__ == '__main__':
    p = Process(target=task, args=('neo', ))
    p.start()
    # p.join()

    print(p.is_alive())
    p.terminate()  # 直接告诉操作系统,终止子进程
    time.sleep(1)
    print(p.is_alive()) # 判断子进程是否存活
    print('主进程', os.getpid())
    print('主主进程', os.getppid())
    
    
'''
True
False
主进程 10708
主主进程 12476
'''

僵尸进程和孤儿进程(了解)

僵尸进程

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

僵尸进程会占用PID号,占用操作系统资源

孤儿进程

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

操作系统内部优化机制:会自动回收没有父的子进程

守护进程

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

from multiprocessing import Process
from multiprocessing import current_process
import time

def task(name):
    print(f'{name} start...', current_process().pid)
    time.sleep(3)
    print(f'{name} over...', current_process().pid)
    print('子进程')

if __name__ == '__main__':
    p = Process(target=task, args=('cwz', ))
    p.daemon = True   # True表示该进程是守护进程
    p.start()
    print('主进程')
    
    
'''
主进程
'''

你可能感兴趣的:(操作系统发展、同步异步阻塞非阻塞、进程)