多道技术

一、简述:单核实现并发。

二、并发与并行

  1、并发:看起来像同时运行的就可以称为并发。

  2、并行:真正意义上的同时运行。

  3、小结:并行属于并发,单核计算机一定无法实现并行,但可以实现并发。

三、机理:计算机的各部分硬件在同时进行的程序中切换地进行工作,并在切换时保存当前进行的状态。

四、作用:可以节省多个程序运行的总耗时。

五、复用

  1、空间上复用:多个程序共用一套计算机硬件。

  2、时间上复用:多个程序完成的总时长等于最长的那个。

六、CPU切换的两种机制

  1、当一个程序遇到IO操作时,操作系统会剥夺该程序的CPU执行权限,这样提高了CPU的利用率,而且也不会影响程序的执行效率。

  2、当一个程序长时间占用CPU的时候,操作系统也会剥夺该程序的CPU执行权限,但是这样会降低程序的执行效率。

七、程序与进程

  1、程序:就是存储于硬盘上的代码,是“死”的。

  2、进程:表示程序正在执行的过程,是“活”的。

八、进程调度机制

  1、先来先服务调度算法:对长时间作业有利,而对短时间作业无益。

  2、短作业优先调度算法:对短时间作业有利,而对长时间作业无益。

  3、时间片轮转法+多级反馈队列:一个程序开启后会先分配固定量的时间片,若经历这些时间片后,程序仍未执行完毕,会被下降到执行优先级低的队列,依次类推,当某个新的程序需要开启时,CPU会立即停止当前程序的执行,跳转到新程序的开启上。

九、程序运行的三状态:就绪态===>运行态===>阻塞态===>就绪态===>运行态。

十、同步与异步

  1、同步:任务提交后,不会先进行其他行为,而在原地等待任务的返回结果,从程序层面看就像是卡住了的感觉。

  2、异步:任务提交后,马上就进行其他行为,任务结束后会通过调回机制自动返回任务结果。

十一、阻塞与非阻塞

  1、阻塞:阻塞态。

  2、非阻塞:就绪态,运行态。

  3、理想状态:让代码永远处于就绪态与运行态之间切换。

十二、异步非阻塞:是最高效的组合。

十三、开启进程:创建进程就是在内存中另外申请一块空间运行代码,多个进程对应多个独立的内存空间,进程与进程之间默认情况下是无法进行直接交互的,若需要交互,必须借助第三方工具、模块等。

# 开启进程的第一种方法:
# windows下创建进程会类似于模块导入,所以需要在执行程序的main里面创建,避免递归创建
# linux下则是直接拷贝一份
import multiprocessing
import time


def test(tag, n):
    print('{}开始了...'.format(tag))
    time.sleep(n)
    print('{}结束了...'.format(tag))


if __name__ == '__main__':
    star_time = time.time()
    p1 = multiprocessing.Process(target=test, args=('aaa', 1))
    p2 = multiprocessing.Process(target=test, args=('bbb', 2))
    p3 = multiprocessing.Process(target=test, args=('ccc', 3))  # 创建三个进程对象
    p1.start()
    p2.start()
    p3.start()  # 开启三个进程
    p1.join()
    p2.join()
    p3.join()  # 声明主程序需要与三个进程同步执行
    end_time = time.time()
    print('三个进程共用时:{}'.format(end_time - star_time))
    print('主程序结束')
'''
结果为:
aaa开始了...
bbb开始了...
ccc开始了...
aaa结束了...
bbb结束了...
ccc结束了...
三个进程共用时:3.089561939239502
主程序结束
'''
# 开启进程的第二种方法:类的继承
import multiprocessing
import time


class MyProcess(multiprocessing.Process):
    def __init__(self, tag, n):
        super().__init__()
        self.tag = tag
        self.n = n

    def run(self):
        print('{}开始了...'.format(self.tag))
        time.sleep(self.n)
        print('{}结束了...'.format(self.tag))


if __name__ == '__main__':
    p = MyProcess('aaa', 1)
    p.start()
    print('主程序先运行')  # 未加join声明,主程序不会等待子进程,而是马上执行自己代码
'''
结果为:
主程序先运行
aaa开始了...
aaa结束了...
'''
# 进程间数据隔离
import multiprocessing
import time

main_tag = 1000


def test(input_tag):
    global main_tag
    main_tag = input_tag  # 子进程声明的全局仍是子进程自己内存空间的全局,不会影响主程序的全局变量
    time.sleep(1)
    print('子进程的:{}'.format(main_tag))


if __name__ == '__main__':
    p = multiprocessing.Process(target=test, args=(3333,))
    p.start()
    print('主程序的:{}'.format(main_tag))
'''
结果为:
主程序的:1000
子进程的:3333
'''

十四、操作系统发展史拓展:鸡哥传送门:https://www.cnblogs.com/Dominic-Ji/articles/10929381.html

猜你喜欢

转载自www.cnblogs.com/caoyu080202201/p/12758141.html