美文网首页
从python角度,理解进程,线程,协程.md

从python角度,理解进程,线程,协程.md

作者: brother阿张 | 来源:发表于2017-04-16 11:37 被阅读0次

写在前面

文中有较多的内容为转载,尽量指出转载来源。

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 # <--- (3) ... and the interpreter is here.

 return z

 return bar(x) # <--- (2) ... which is returning a call to bar ...

foo() # <--- (1) We're in the middle of a call to foo ...

那么,相应的调用栈如下,一个py文件,一个类,一个函数都是一个代码块,对应者一个Frame,保存着上下文环境以及字节码指令。

c ---------------------------

a | bar Frame | -> block stack: []

l | (newest) | -> data stack: [1, 2]

l ---------------------------

 | foo Frame | -> block stack: []

s | | -> data stack: [<Function foo.<locals>.bar at 0x10d389680>, 1]

t ---------------------------

a | main (module) Frame | -> block stack: []

c | (oldest) | -> data stack: [<Function foo at 0x10d3540e0>]

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:作为正常结果返回

[2] 生成器的源码分析 http://www.cnblogs.com/coder2012/p/4990834.html
[3] Stackless Python 探秘 http://shymonk.com/posts/2016/06/stackless-python-tan-mi/

相关文章

  • 从python角度,理解进程,线程,协程.md

    写在前面 文中有较多的内容为转载,尽量指出转载来源。 1 进程(process) 定义:进程是正在运行程序的实例。...

  • Python-02进阶-04多进程多线程

    Python 进阶-04 进程线程协程并发等.md tags: Python 多进程 并发 进阶 必备知识 201...

  • python笔记3

    python 无线程池 ,有进程池 阻塞 意外着等待子进程结束 字典的无序性 : 进程,线程,协程 协程,又称微...

  • 关于kotlin 协程Coroutines

    Coroutines 协程是什么 从 Android 开发者的角度去理解协程 (Coroutines) 和线程 (...

  • Gevent高并发网络库精解

    进程 线程 协程 异步 并发编程(不是并行)目前有四种方式:多进程、多线程、协程和异步。 多进程编程在python...

  • Go 协程调度的个人理解

    1.1 协程与进程的区别 首先,我理解的操作系统调度等级为 进程 —— 线程 —— 协程。其中进程和线程的区别是本...

  • Unity协同函数简介

    协程的概念 协程又可以称为用户线程,微线程,可以将其理解为单个进程或线程中的多个用户态线程,这些微线程在用户态进程...

  • 十分钟看懂:Java并发——协程

    协程 协程可以理解为一种轻量级的线程 从操作系统的角度来看,线程是在内核态中调度的,而协程是在用户态调度的,协程的...

  • python多线程、多进程、协程的使用

    python多线程、多进程、协程的使用 本文主要介绍多线程、多进程、协程的最常见使用,每个的详细说明与介绍有时间会...

  • python常用知识

    多线程,多进程,协程进程池 协程 字典 列表 函数 文件操作

网友评论

      本文标题:从python角度,理解进程,线程,协程.md

      本文链接:https://www.haomeiwen.com/subject/zdhaattx.html