python学习之并发编程(理论部分)
第一章 操作系统
管理控制协调计算机中硬件与软件的关系.
-
操作系统的作用?
第一个作用: 将一些对硬件操作的复杂丑陋的接口,变成简单美丽的接口. open函数.
第二个作用: 多个进程抢占一个(cpu)资源时,从操作系统会将你的执行变得合理有序.
阻塞: input read write sleep recv accept sendto recvfrom .....
1.操作系统的发展史
最早出现的计算机: 算盘.
电子类的计算机发展史:
第一代计算机1940~1955
在大学里出现了机房,想使用计算机必须预约. 先连接调配各个硬件,1.5小时, 真空管, 然后在插上程序调试.效率低. 优点: 个人独享整个计算机资源. 缺点: 1. 硬件调试插线,耗时 2. 所有人都是串行执行.
第二代计算机 磁带存储---批处理系统 1955~1965
优点: 程序员不用亲自对硬件进行插线操控,效率提高. 可以进行批量处理代码. 缺点: 程序员不能独自使用计算机. 你的所有程序还是串行.
第三代计算机:集成电路,多道程序系统
大背景:
1.集成电路: 把所用的硬件变小,线路板. 2.将两套不同的生产线合并成一条生产线.
技术上的更新: 多道技术.
1. 空间上的复用: 将内存分区域,一个内存可以同时加载多个进程. 2. 时间上的复用: 实现将cpu在多个进程之间来回切换,并且保留状态.
几乎所有的程序又有io阻塞
同时加载到内存 3个任务,3个进程,每个进程都有阻塞情况,只要cpu运行一个进程时,遇到io阻塞立马回切换,长时间占用cpu也会切换.
提升效率,最大限度的使用cpu.
如果是一个io密集型进程,来回切换提升效率.
如果是一个计算密集型,来回切换降低效率.
第三代计算机广泛采用了必须的保护硬件(程序之间的内存彼此隔离)之后,第三代计算机应用而生:
每个人占用计算机的时间有限的,
多人(少于10个) 共同使用一个计算机主机,
第四代计算机: 1980 - 至今
1.个人计算机操作系统
个人计算机上的操作系统是联机交互的单用户操作系统,它提供的联机交互功能与通用分时系统提供的功能很相似。
由于是个人专用,因此一些功能会简单得多。然而,由于个人计算机的应用普及,对于提供更方便友好的用户接口和丰富功能的文件系统的要求会愈来愈迫切。
2.网络操作系统
计算机网络:通过通信设施,将地理上分散的、具有自治功能的多个计算机系统互连起来,实现信息交换、资源共享、互操作和协作处理的系统。
网络操作系统:在原来各自计算机操作系统上,按照网络体系结构的各个协议标准增加网络管理模块,其中包括:通信、资源共享、系统安全和各种网络应用服务。
就是添加了一些网络方面的功能。
3.分布式操作系统
表面上看,分布式系统与计算机网络系统没有多大区别。分布式操作系统也是通过通信网络,将地理上分散的具有自治功能的数据处理系统或计算机系统互连起来,实现信息交换和资源共享,协作完成任务。——硬件连接相同。
分布式:将一个大的任务拆分成几个小的任务,分配给不同的任务处理机制,具体怎么分配是由系统中的算法决定的,大家同时来运行自己的任务,然后各自将人物的返回结果再返回给你这个大的任务。
但有如下一些明显的区别:
(1)分布式系统要求一个统一的操作系统,实现系统操作的统一性。
(2)分布式操作系统管理分布式系统中的所有资源,它负责全系统的资源分配和调度、任务划分、信息传输和控制协调工作,并为用户提供一个统一的界面。
(3)用户通过这一界面,实现所需要的操作和使用系统资源,至于操作定在哪一台计算机上执行,或使用哪台计算机的资源,则是操作系统完成的,用户不必知道,此谓:系统的透明性。
(4)分布式系统更强调分布式计算和处理,因此对于多机合作和系统重构、坚强性和容错能力有更高的要求,希望系统有:更短的响应时间、高吞吐量和高可靠性。
分布式系统已经很普遍了,一般个人用不到,企业在处理比较大的任务
第二章 进程的基础
1.程序
一堆静态的代码文件.
2.进程
一个正在运行的程序进程. 抽象的概念. 由操作系统操控调用交于cpu运行 被cpu运行.
第三章 并发和并行
无论是并行还是并发,在用户看来都是'同时'运行的,不管是进程还是线程,都只是一个任务而已,真是干活的是cpu,cpu来做这些任务,而一个cpu同一时刻只能执行一个任务
串行: 所有的任务一个一个的完成. 并发: 一个cpu完成多个任务.看起来像是同时完成. 并行: 多个cpu执行多个任务,真正的同时完成.
第四章 同步|异步and阻塞|非阻塞
同步: 发起同步调用后,就在原地等着任务结束,根本不考虑任务是在计算还是在io阻塞,总之就是一股脑地等任务结束
异步: 发起异步调用后,并不会等待任务结束才返回,相反,会立即获取一个临时结果(并不是最终的结果,可能是封装好的一个对象)
阻塞: cpu遇到io就是阻塞.
非阻塞: 没有io,就叫非阻塞.
第五章 进程的创建:
一个子进程必须依赖于一个主进程才可以开启.
一个主进程可以开启多个子进程.
unix: fork创建子进程. unix(linux,mac): 创建一个子进程会完完全全复制一个主进程所有的资源,初始资源不变. windows: 操作系统调用createprocess 处理进程的创建. windows:创建一个子进程,会copy主进程所有的资源,但是会改变一些资源.
第六章 进程的终止
1. 正常退出(自愿,如用户点击交互式页面的叉号,或程序执行完毕调用发起系统调用正常退出,在linux中用exit,在windows中用exitprocess) 2. 出错退出(自愿,python a.py中a.py不存在) 3. 严重错误(非自愿,执行非法指令,如引用不存在的内存,1/0等,可以捕捉异常,try...except...) 4. 被其他进程杀死(非自愿,如kill -9)
第七章 进程的层次结构
无论unix还是windows,进程只有一个父进程,不同的是: 1. 在unix中所有的进程,都是以init进程为根,组成树形结构。父子进程共同组成一个进程组,这样,当从键盘发出一个信号时,该信号被送给当前与键盘相关的进程组中的所有成员。 2. 在windows中,没有进程层次的概念,所有的进程都是地位相同的,唯一类似于进程层次的暗示,是在创建进程时,父进程得到一个特别的令牌(称为句柄),该句柄可以用来控制子进程,但是父进程有权把该句柄传给其他子进程,这样就没有层次了。
第八章 进程的状态:
tail -f access.log |grep '404'
执行程序tail,开启一个子进程,执行程序grep,开启另外一个子进程,两个进程之间基于管道'|'通讯,将tail的结果作为grep的输入。
进程grep在等待输入(即i/o)时的状态称为阻塞,此时grep命令都无法运行
其实在两种情况下会导致一个进程在逻辑上不能运行,
- 进程挂起是自身原因,遇到i/o阻塞,便要让出cpu让其他进程去执行,这样保证cpu一直在工作
- 与进程无关,是操作系统层面,可能会因为一个进程占用时间过多,或者优先级等原因,而调用其他的进程去使用cpu。
因而一个进程由三种状态
第九章 进程并发的实现
进程并发的实现在于,硬件中断一个正在运行的进程,把此时进程运行的所有状态保存下来,为此,操作系统维护一张表格,即进程表(process table),每个进程占用一个进程表项(这些表项也称为进程控制块)
该表存放了进程状态的重要信息:程序计数器、堆栈指针、内存分配状况、所有打开文件的状态、帐号和调度信息,以及其他在进程由运行态转为就绪态或阻塞态时,必须保存的信息,从而保证该进程在再次启动时,就像从未被中断过一样。
下一篇: 解析网页的写法汇总