深入理解python.md_从python角度,理解进程,线程,协程.md-Go语言中文社区
写在前面
文中有较多的内容为转载,尽量指出转载来源。
1 进程(process)
定义:进程是正在运行程序的实例。
如chrome 进程的三种状态:
就绪态
执行态
阻塞态
进程是基于计算机系统的异常。进程切换是需要保存上下文环境(一些寄存器,以及栈的信息。 子进程和父进程具有相同的文件描述符。 不同的进程具有不同的地址空间,变量无法共享。调度有操作系统完成。process 由 process control block (PCB)控制 ;。
2 线程(thread)
一个进程,包含多个线程 线程是一种轻量进程,实际上在linux内核中,两者几乎没有差别,除了一点——线程并不产生新的地址空间和资源描述符表,而是复用父进程的。线程的调度和进程一样,都必须陷入内核态。调度有操作系统完成(thread 由 thread control blocks (TCBs)控制)。 线程模型主要通过陷入切换上下文。。
多线程的地址空间.png
3 协程(coroutine)
一个线程,包含多协程。协程由应用程序实现调度,线程由操作系统实现调度,不需要陷入内核。
3.1 函数调用[2]
函数,所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。
函数的调用 是通过栈来实现的,一个线程就是执行一个子函数 栈帧保存了给出代码的的信息和上下文,其中包含最后执行的指令,全局和局部命名空间,异常状态等信息。f_valueblock保存了数据,b_blockstack保存了异常和循环控制方法
def foo():
x = 1
def bar(y):
z = y + 2 #
return z
return bar(x) #
foo() #
那么,相应的调用栈如下,一个py文件,一个类,一个函数都是一个代码块,对应者一个Frame,保存着上下文环境以及字节码指令。
c ---------------------------
a | bar Frame | -> block stack: []
l | (newest) | -> data stack: [1, 2]
l ---------------------------
| foo Frame | -> block stack: []
s | | -> data stack: [.bar at 0x10d389680>, 1]
t ---------------------------
a | main (module) Frame | -> block stack: []
c | (oldest) | -> data stack: []
k ---------------------------
携程看起来像函数,但是内部可以中断。举例如
def A():
print '1'
print '2'
print '3'
def B():
print 'x'
print 'y'
print 'z'
假设程序是由携程执行的,,在执行A的过程中,可以随时中断,去执行B,B也可能在执行过程中中断再去执行A,结果可能是:
1
2
x
y
3
z
3.2 协程的实现 [3]
并发模型
image.png
并发系统从本质上讲,是一系列独立的执行单元(routine)在调度器的调度之下交替执行。与线程相比,协程并发模型与其最大不同之处在于:协程由应用程序实现调度,线程由操作系统实现调度
由于协程作为执行单元并发执行时,会因为主动放弃执行权限而被挂起,调度系统必须同时维护多个函数执行上下文,以实现非本地跳转(non-local jump)。
C-Python解释器栈结构以及它是如何工作的。
def a(x):
b(x + 1)
def b(x):
c(x * x)
def c(x):
print 'x=',x
a(42)
在CPython shell中执行上面这段代码时,Python-Stack与 C-Stack结构如下图。
image.png
Python虚拟机以eval_code2作为解释函数执行a时,首先通PyFrame_New构造a的栈帧frame-a并返回eval_code2,然后执行a对应的Python代码。由于a嵌套调用b,此时解释器递归调用eval_code2并重复之前过程执行b,从而形成C-stack和由PyFrameObject构成的python-stack。
范式转换对于stackfull的标准Python而言,实现协程并发的核心在于将Python-Stack与 C-Stack解耦,这种改变Python解释器执行过程的方法也被称作范式转换。要点可以归纳为以下三个方面:
1.函数栈帧执行时机
解释器执行Python函数的标准范式是:为函数的PyCodeObject
构造一个函数栈帧PyFrameObject并附带所有参数,最后通过eval_code2
解释执行相应的函数体直到其返回。然而,以正确的调用顺序执行所有的函数栈帧并不意味着我们必须在当前C-stack嵌套层级中执行eval_code2。如果我们能够避免与C-stack相关的所有后续操作,就可以在函数栈帧执行前实现C-stack的退栈操作,从而达到解耦的目的。
2.参数生命周期
在标准python中,函数参数的引用由其上层调用者持有。这意味着只有下层函数返回后,其参数元组的引用才能被上层函数销毁。
现在,让我们换一种思维方式。很明显,函数参数应该与函数栈帧有着相同的生命周期,参数元组的引用也应该同函数栈帧一起被销毁。所以,我们在PyFrameObject结构中添加对参数元组的引用,就可以实现范式的转换。
3.系统状态
在标准python中,执行一个函数栈帧后的返回值会存在两种情况:
返回PyObject:代表函数正常执行。
返回NULL:代表函数抛出异常。
基于这两种基本系统状态,添加一个特殊的返回值类型Py_UnwindToken
作为第三种系统状态,这样我们便可以在下层栈帧被执行之前实现C-stack
退栈操作。
由于Py_UnwindToken与其他Python对象兼容,这一范式的转换对于大部分相关代码并不可见,我们只需要对执行栈帧的C函数做出修改即可。Return Value系统状态:
NULL:函数执行异常
Py_UnwindToken:调度函数栈帧
Other PyObject:作为正常结果返回
深入理解python.md_从python角度,理解进程,线程,协程.md-Go语言中文社区相关推荐
- Python之进程+线程+协程(异步、selectors模块、阻塞、非阻塞IO)
文章目录 一.IO多路复用 二.selectors模块 本篇文字是关于IO多路复用的更深入一步的总结,上一篇 Python之进程+线程+协程(事件驱动模型.IO多路复用.select与epoll)对I ...
- python进程线程协程区别_Python3多线程与协程
python中的多线程非常的常用,之前一直糊里糊涂地使用,没有一些系统性的概念,记录一下~ 0x001 多线程的优势:可将长时间占用的程序放到后台 可能会加速程序执行速度 能够实现一些类似同步执行的效 ...
- Python之进程+线程+协程(并发与并行、GIL锁、同步锁、死锁、递归锁)
文章目录 一.并发与并行 二.同步与异步 三.线程锁 1.GIL全局解释器锁 2.同步锁 3.死锁 4.递归锁 在Python中GIL解释器锁.同步锁.死锁.递归锁都是什么?怎么这么多锁,它们都是用来 ...
- python进程线程协程区别_进程和线程、协程的区别
现在多进程多线程已经是老生常谈了,协程也在最近几年流行起来.python中有协程库gevent,py web框架tornado中也用了gevent封装好的协程.本文主要介绍进程.线程和协程三者之间的区 ...
- 4.19 python 网络编程和操作系统部分(TCP/UDP/操作系统概念/进程/线程/协程) 学习笔记
文章目录 1 网络编程概念 1)基本概念 2)应用-最简单的网络通信 2 TCP协议和UDP协议进阶(网络编程) 1)TCP协议和UDP协议基于socket模块实现 2)粘包现象 3)文件上传和下载代 ...
- python 进程 线程 协程
并发与并行:并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同一时间间隔内发生.在单核CPU下的多线程其实都只是并发,不是并行. 进程是系统资源分配的最小单位,进程的出现是为了更好的 ...
- 进程 线程 协程_进程 线程 协程 管程 纤程 概念对比理解
不知道是不是我自己本身就有那么一丝丝的密集恐惧,把这么一大堆看起来很相似很相关的概念放在一起,看起来是有点麻,捋一捋感觉舒服多了. 相关概念 任务.作业(Job,Task,Schedule) 在进程的 ...
- Python之进程+线程+协程(multiprocessing多进程模块)
前几篇的多线程模块的各种规则和用法,本篇则是关于多进程模块的内容 1.multiprocessing的介绍 在Python中,由于有GIL解释器锁的存在,多线程就根本不是本质意义上的多线程,而是一个主 ...
- Python之进程+线程+协程(同步对象、信号量、队列)
文章目录 Event同步对象 semaphore信号量 队列 本篇是关于Python进程方面的内容了,主要是Event同步对象,信号量和队列 Event同步对象 1.概念: 我们可以对一个线程set一 ...
- Python之进程+线程+协程(进程的本质 与 threading线程模块)
文章目录 基本概念 threading线程模块 本篇开始分析Python中的并发程序,也就是进程.线程.协程序的使用.由于是用自己的语言总结的,因此比较大白话,或者叫通俗易懂.而且很多细节方面没有具体 ...
最新文章
- 大学生计算机基础excel视频,大学生计算机基础Excel.doc
- 用Cobertura 测量测试覆盖率
- React v15.0 正式版发布
- jsp session
- 相交链表—leetcode160
- 使用区分优先级的负载分流法确保Netflix的可靠性
- matlab图像边缘检测分析
- 【树莓派】树莓派3B安装宝塔面板并配置安装LNMP
- [BZOJ3676][Apio2014]回文串
- linux-2.6内核模块引用计数的实现(try_module_get和module_put)
- Windows 的开发好痛苦
- 世界大学生超算竞赛正式启动,再次引发全球关注
- Tomcat 7 的七大新特性
- 服务器器ip的A段B段C段是什么意思有什么意义
- 利用InVEST模型的生境质量模块计算生境质量
- VirtualBox添加USB 3.0控制器扩展
- STM32单片机USB扫码枪开发笔记
- 基于存储卡的音乐播放器0.6
- 如何求一个平面区域中心点问题--编程实现
- CentOs 7源码安装 Python3
热门文章
- [詹兴致矩阵论习题参考解答]习题1.10
- 常用SQL语句---备忘
- 【报告分享】2021年度私域经营洞察报告.pdf(附下载链接)
- leetcode力扣454. 四数相加 II
- Network-based Fraud Detection for Social Security Fraud
- android 动画坐标,Android 动画之TranslateAnimation应用详解
- python数据分析实况_Python数据分析实战:降雨量统计分析报告分析
- oracle数据库dca,有关Oracle数据库
- 吴恩达《机器学习》第九章:神经网络的学习
- 数学建模 聚类模型