重新理解变量在函数内作用域和栈的关系
引子
以前对于函数作用域和栈的关系非常不清晰,只知道栈是系统为一个程序预分配的一块空间,程序的预声明变量都存在系统的栈当中,用malloc*分配的空间则在堆当中。
“作用域”和“栈”是一个抽象的概念,并没有深入的理解他们之间的联系。
一直以来都对代码如何在计算机中运行这一块饶有兴趣,最近刚好有时间来了解一下这里面的原理。
以前对于函数作用域和栈的关系非常不清晰,只知道栈是系统为一个程序预分配的一块空间,程序的预声明变量都存在系统的栈当中,用malloc*分配的空间则在堆当中。
“作用域”和“栈”是一个抽象的概念,并没有深入的理解他们之间的联系。
一直以来都对代码如何在计算机中运行这一块饶有兴趣,最近刚好有时间来了解一下这里面的原理。
引子
以前对Gevent(Greenlet)为什么比Thread快,只有一个隐约的理解,之前的看到过的说法是,上下文切换的成本上,Greenlet比Thread低很多,但是具体低在哪些地方呢?
刚好这段时间阅读了CSAPP,对这个问题又有了新的看待的角度:)
参考了如下三篇文章和greenlet的实现:
https://www.ibm.com/developerworks/cn/linux/kernel/l-thread/
http://stackoverflow.com/questions/15556718/greenlet-vs-threads
http://www.jianshu.com/p/cd41c14b19f4
Greenlet VS Thread
相同点
都进行了寄存器内容的保存,保存了栈的内容以便将来恢复
不同点
如下几件事情,是协程切换不用做的事情
少了一些system call,自己主动保存/恢复寄存器信息。
不需要管理复杂的线程数据结构然后再到Python VM里面管理字节码,比如CLONE_FS,CLONE_FILES,CLONE_SIGHAND等操作都不需要进行
没有mmap操作
综上所述,协程的创建和上下文切换成本中,两者都需要进行寄存器状态保存,但用户态的协程,少了很多额外操作,因此更加轻量。