第二十八天:进程

操作系统发展史

穿孔卡片

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

缺点: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()

posted @ 2019-10-21 21:05  KONNE  阅读(197)  评论(0编辑  收藏  举报