当前位置:
首页 > temp > 简明python教程 >
-
【2020Python修炼记】python并发编程(一)多进程
一、操作系统发展史
1、第一代计算机(1940~1955):真空管和穿孔卡片
(1)特点: 没有操作系统的概念 所有的程序设计都是直接操控硬件
(2)优点:程序员在申请的时间段内独享整个资源,可以即时地调试自己的程序(有bug可以立刻处理)
(3)缺点:浪费计算机资源,一个时间段内只有一个人用。 注意:同一时刻只有一个程序在内存中,被cpu调用执行,比方说10个程序的执行,是串行的。
2、第二代计算机*(1955~1965)*:晶体管和批处理系统
(1)特点:设计人员、生产人员、操作人员、程序人员和维护人员直接有了明确的分工,计算机被锁在专用空调房间中,由专业操作人员运行,这便是‘大型机’。
(2)优点:批处理,节省了机时
(3)缺点:
1.整个流程需要人参与控制,将磁带搬来搬去(中间俩小人)
2.计算的过程仍然是顺序计算-》串行
3.程序员原来独享一段时间的计算机,现在必须被统一规划到一批作业中,等待结果和重新调试的过程都需要等同批次的其他程序都运作完才可以(这极大的影响了程序的开发效率,无法及时调试程序)
3、第三代计算机*(1965~1980)*:集成电路芯片和多道程序设计
(1)特点: 第三代计算机的操作系统广泛应用了第二代计算机的操作系统没有的关键技术:多道技术
分时操作系统: 多个联机终端+多道技术
4、第四代计算机**(1980~至今):个人计算机**
即使可以利用的cpu只有一个(早期的计算机确实如此),也能保证支持(伪)并发的能力。
将一个单独的cpu变成多个虚拟的cpu(多道技术:时间多路复用和空间多路复用+硬件上支持隔离),没有进程的抽象,现代计算机将不复存在。
5、操作系统的作用
1:隐藏丑陋复杂的硬件接口,提供良好的抽象接口
2:管理、调度进程,并且将多个进程对硬件的竞争变得有序
二、进程发展史及算法演变
1、什么是进程(Process)
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;
在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。
2、操作系统引进进程概念的原因
从理论角度看,是对正在运行的程序过程的抽象;
从实现角度看,是一种数据结构,目的在于清晰地刻画动态系统的内在规律,有效管理和调度进入计算机系统主存储器运行的程序。
3、进程的并行与并发
(1)并行 : 并行是指两者同时执行。比如赛跑,两个人都在不停的往前跑;(资源够用,比如三个线程,四核的CPU )
(2)并发 : 并发是指资源有限的情况下,两者交替轮流使用资源。比如一段路(单核CPU资源)同时只能过一个人,A走一段后,
让给B,B用完继续给A ,交替使用,目的是提高效率。
(3)区别:
并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,这就要求必须有多个处理器。
并发是从宏观上,在一个时间段上可以看出是同时执行的,比如一个服务器同时处理多个session。
三、多道技术——空间上的复用+时间上的复用
1.产生背景:针对单核,实现并发
ps: 现在的主机一般是多核,那么每个核都会利用多道技术 有4个cpu,运行于cpu1的某个程序遇到io阻塞,
会等到io结束再重新调度,会被调度到4个 cpu中的任意一个,具体由操作系统调度算法决定。
2.空间上的复用:如内存中同时有多道程序
3.时间上的复用:复用一个cpu的时间片
强调:遇到io切,占用cpu时间过长也切,核心在于切之前将进程的状态保存下来,
这样 才能保证下次切换回来时,能基于上次切走的位置继续运行
四、同步异步/阻塞非阻塞概念
1、进程三态——就绪态,运行态,阻塞态
在程序运行的过程中,由于被操作系统的调度算法控制,程序会进入几个状态:就绪,运行和阻塞。
(1)就绪(Ready)状态
当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。
(2)执行/运行(Running)状态
当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。
(3)阻塞(Blocked)状态
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,
例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。
2、同步/异步——描述的是任务的提交方式,即 针对的是函数/任务的调用方式
(1)所谓同步,就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列
。要么成功都成功,失败都失败,两个任务的状态可以保持一致。即 在发出一个功能调用时,在没有得到结果之前,该调用就不会返回。
——例如:啥也不干,干等着你,等你一起吃饭
(2)所谓异步,是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了
。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列
。即 异步的概念和同步相对。当一个异步功能调用发出后,调用者不能立刻得到结果。当该异步功能完成后,通过状态、通知或回调来通知调用者。
——例如:通知你去吃饭,然后自己先忙别的,等你忙完了再决定吃不吃饭
3、阻塞/非阻塞——描述的程序的运行状态,即 针对的是进程或线程
阻塞和非阻塞,这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。
也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的
(1)阻塞
# 阻塞调用是指调用结果返回之前,当前线程会被挂起(如遇到io操作)。函数只有在得到结果之后才会将阻塞的线程激活。
有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。
#举例:
#1. 同步调用:apply一个累计1亿次的任务,该调用会一直等待,直到任务返回结果为止,但并未阻塞住(即便是被抢走cpu的执行权限,那也是处于就绪态);
#2. 阻塞调用:当socket工作在阻塞模式的时候,如果没有数据的情况下调用recv函数,则当前线程就会被挂起,直到有数据为止。
(2)非阻塞
# 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前也会立刻返回,同时该函数不会阻塞当前线程。
五、创建进程的两种方式
1、
# 第一种 from multiprocessing import Process import time def task(name): print('%s is running'%name) time.sleep(3) print('%s is over'%name) if __name__ == '__main__': # 1 创建一个对象 p = Process(target=task, args=('jason',)) # 容器类型哪怕里面只有1个元素 建议要用逗号隔开 # 2 开启进程 p.start() # 告诉操作系统帮你创建一个进程 异步 print('主') """ windows操作系统下 创建进程一定要在main内创建 因为windows下创建进程类似于模块导入的方式 会从上往下依次执行代码 linux中则是直接将代码完整的拷贝一份 """
2、
# 第二种方式 类的继承 from multiprocessing import Process import time class MyProcess(Process): def run(self): print('hello bf girl') time.sleep(1) print('get out!') if __name__ == '__main__': p = MyProcess() p.start() print('主')
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数