临界资源:虽然多个进程可以共享系统中的各种资源,但其中许多资源一次只能为一个进程所使用,我们把一次仅允许一个进程使用的资源称为临界资源
堆:堆是应用程序在运行的时候请求操作系统分配给自己内存,一般是申请/给予的过程。https://jingyan.baidu.com/article/6c67b1d6a09f9a2786bb1e4a.html
栈:栈是指一种使用堆的方法,是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有FIFO(先进先出)的特性,在编译的时候可以指定需要的Stack的大小。进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)。
协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。
进程:进程,是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。用非官方的白话来解释就是——执行中的程序是进程,比如qq不是进程,但是当我们双击qq开始使用它的时候,它就变成了一个进程。我们写的python程序,只有当我们执行它的时候,它才是进程。我们正在执行的IE浏览器,QQ,pycharm都是进程,从操作系统的角度来讲,每一个进程都有它自己的内存空间,进程之间的内存是独立的
http://www.cnblogs.com/Eva-J/p/5106688.html
线程:线程,有时被称为轻量级进程,是程序执行流的最小单元。我们可以理解为,线程是属于进程的,我们平时写的简单程序,是单线程的,多线程和单线程的区别在于多线程可以同时处理多个任务,这时候我们可以理解为多线程和单线程的多进程是一样的,我可以在我的进程中开启一个线程放音乐,也可以开启另外的线程聊qq,但是进程之间的内存独立,而属于同一个进程多个线程之间的内存是共享的,多个线程可以直接对它们所在进程的内存数据进行读写并在线程间进行交换。
协程:协程是一种用户态的轻量级线程。如果说多进程对应多CPU,多线程对应多核CPU,那么协程则是在充分挖掘不断提高性能的单核CPU的潜力。我们既可以利用异步优势,又可以避免反复系统调用,还有进程切换造成的开销,这就是协程。协程也是单线程,但是它能让原来要使用异步+回调方式写的非人类代码,可以用看似同步的方式写出来。它是实现推拉互动的所谓非抢占式协作的关键。协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。http://blog.csdn.net/hairetz/article/details/16119911
执行一个Python程序,相当于开始了一个进程。程序中有多个子程序,也就是函数,函数是层级调用,比如比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。子程序调用总是一个入口,一次返回,调用顺序是明确的。
而协程的调用和子程序不同。协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点类似CPU的中断。比如子程序A、B:
def A(): def B():
print '1' print 'x'
print '2' print 'y'
print '3' print 'z'
假设由协程执行,在执行A的过程中,可以随时中断,去执行B,B也可能在执行过程中中断再去执行A,结果可能是:
1
2
x
y
3
z
但是在A中是没有调用B的,所以协程的调用比函数调用理解起来要难一些。看起来A、B的执行有点像多线程,但协程的特点在于是一个线程执行
那和多线程比,协程有何优势?最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
多进程和多线程的区别:二者的最大区别就是, 是否共享资源, 后者是共享资源的,而前者是独立的。所以多进程拥有更好的安全性。相对于进程的轻型特征,多线程环境有个最大的问题就是 如何保证资源竞争,死锁, 数据修改等.于是,便有了线程安全 (thread safety)的提出
线程安全:是在多线程的环境下, 线程安全能够保证多个线程同时执行时程序依旧运行正确, 而且要保证对于共享的数据,可以由多个线程存取,但是同一时刻只能有一个线程进行存取.http://www.cnblogs.com/mindsbook/archive/2009/10/15/thread-safety-and-GIL.html#id1
加锁:加锁可以保证存取操作的唯一性,从而保证同一时刻只有一个线程对共享数据存取。Python中使用的全局锁机制,即GIL(Global Interpreter Lock)
调度其实是操作系统来进行的,每次进程或者线程的调度会消耗较大,这个操作时OS的内核去完成的。每次线程或者进程被调度后,需要给线程准备运行的环境
这个准备环境的过程包括把上一个运行的线程占用的资源如寄存器,缓存,内存管理单元等释放掉,然后在把新线程的这些东西加载进去。同一个进程内的线程切换比不同进程的线程切换,花的时间更长,也更消耗CPU的资源。而协程呢,其实就是在线程内写了一个线程调度算法
协程就是特殊的线程,在协程中写入了一个调度算法,节省调度的开销
还有另外一种实现模式:异步--就是在程序处理过程中,当碰见阻塞的时候,这个时候,就把当前处理的业务的上下文保存下来,然后去处理其他的业务,等被阻塞的业务需要的数据得到以后,再找到对应的这个数据,然后继续后面的处理。协程也是碰到阻塞主动切出去,数据回来的时候再找到对应的协程,继续后续的处理