进程课堂小结day29

昨日回顾

操作系统发展史

  • 穿孔卡片

  • 联机批处理

  • 脱机批处理

  • 多道技术:

    ​ 单道:多个程序一串串执行

    ​ 多道:

    ​ 切换+保存状态

    • 空间上的复用

      一个计算机(CPU)的空间可以提供给多个程序使用.

    • 时间上的复用

      当前程序遇到IO操作,就会立马切换CPU的执行权限

      当前程序使用CPU时间过长,就会立马切换CPU的执行权限

  • 并发与并行

    • 并发:看起来像同时运行。
    • 并行:真是意义上的同时运行。
    • 在单核的情况下不能实现并行,要想实现并行,必须有多个CPU

进程

  • 程序:一堆代码。

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

  • 进程调度:时间片论法 + 分级反馈队列

  • 进程的三种状态:

    • 就绪态

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

    • 运行态

      通过进程调度将每一个进程调入运行态

    • 阻塞态

      在运行态中的程序遇到IO就会进入阻塞态

      若IO结束,会立马进入就绪态,不会直接进入运行态

      注意:CPU的执行时间过长会看起来像阻塞,其实并不是阻塞,剥夺其CPU执行权限,然后会将该进程重新返回就绪态。

  • 同步与异步

    • 同步:一个任务提交后,在原地等待该任务结束后,下一个才能提交并且执行
    • 异步:一个任务提交后,不需要原地等待,立马可以执行下一个任务
  • 阻塞与非阻塞

    • 阻塞:阻塞态(遇到IO,会进入阻塞态)
    • 非阻塞:就绪态、运行态
  • 创建进程的两种方式

    • from multiprocessing import Process
    • import time

    方式一:

    def task():
        print('子进程开始执行')
        time.sleep(1)
        print('子进程结束完毕')
        # 在windows系统下创建,必须要再__main__执行
        - __main__ 下:
        # target = 执行任务(函数地址)
        p = Process(target = task)
        p.start() #告诉操作系统,创建子进程
        
        # join
        p.join() # 让主进程等待所有子进程结束后才能结束
        print('主进程')
    

    方式二:

    - 自定义类,继承Process
    class Myprocess(Process):
        def run(self):
            # 此处是子进程的任务
            print('子进程开始执行')
            time.sleep(1)
            print('子进程结束完毕')
            
    	- __main__下:
        	p = MyProcess()
            p.start() # 告诉操作系统,创建子进程
            # join
            p.join() # 让主进程等待所有子进程结束后才结束
            print('主进程')
    
    • join() 让主进程等待所有子进程结束后才能结束
    • 进程间数据是隔离的
    • 进程对象的属性
    # 可以获取子进程 pid号
    current_process().pid --->return Process().pid
    # 在子进程中打印是子进程的pid号,在父进程中打印父进程的pid号
    os.getpid()
    # 主主进程pid号
    os.getppid()
    
    current_process()-->p
    # 终止子进程
    p.terminate()
    # 判断进程是否存活
    is_alive
    
  • 守护进程

    主进程结束后,子进程也要跟着结束

    # 注意:必须要在start()之前设置
    p.daemon = True
    p.start()
    # p.daemon = True 报错
    
  • 父进程回收子进程PID号的两种方式:

    • join
    • 父进程正常结束后
  • 僵尸进程与孤儿进程(了解):

    • 僵尸进程:子进程结束后,父进程没有回收PID,导致子进程永久保留PID

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

    • 孤儿进程:子进程还未结束,父进程意外结束,导致子进程在结束后父进程无法回收

      此使子进程就像一个"孤儿",然后由操作系统自带的"福利院"来回收.
      

进程互斥锁

img

串行

​ A和B两个任务运行在一个CPU线程上,在A任务执行完之前不可以执行B。即,在整个程序的运行过程中,仅存在一个运行上下文,即一个调用栈一个堆。程序会按顺序执行每个指令。

进程互斥锁

​ 让并行变串行,牺牲了执行效率、保证了数据安全,保证了数据安全,

在程序并发执行时,需要修改数据时使用。

队列

​ 队列:先进先出

相当于一个内存中产生一个队列空间,可以存放多个数据,但数据的顺序是由先进去的排前面。

堆栈

先进后出

IPC(进程间通信)

进程间数据是相互隔离的,若想实现进程间通信,可以利用队列

生产者与消费者

​ 生产者:生产数据的

​ 消费者:使用数据的

生活中:卖油条,一边生产油条,一边卖油条,供需不平衡

程序中:通过队列,生产者把数据添加队列中,消费者从队列中获取数据

线程

定义:线程与进程都是虚拟单位,目的是为了更好地描述某种事物。

- 进程:资源单位
- 线程:执行单位

开启一个进程,一定会有一个线程,线程才是真正的执行者。

为什么要使用线程?

​ 节省内存资源.

  • 开启进程:
    • 开辟一个名称空间,每开启一个进程都会占用一份内存资源
    • 会自带一个线程
  • 开启线程:
    • 一个进程可以开启多个线程
    • 线程的开销远小于进程

注意:内存就像一个工厂,子进程就像一个工厂车间,线程就像车间内的流水线

线程之间数据是共享的

原文地址:https://www.cnblogs.com/shin09/p/11721937.html