py 并发编程

串行、并发、并行

并行是多核同时运行,同时运行不一样的线程,并发是在单核下模拟并行,相似于时间片轮转来处理多个线程,使之看起来像并行html

同步、异步、阻塞、非阻塞

同步:在发出一个功能调用时,在没有获得结果以前,该调用就不会返回。python

异步:当一个进程发起一个函数(任务)调用的时候,不会等函数返回,而是继续往下执行当,函数返回的时候经过状态、通知、事件等方式通知进程任务完成。linux

阻塞:阻塞调用是指调用结果返回以前,当前线程会被挂起(如遇到io操做)。函数只有在获得结果以后才会将阻塞的线程激活nginx

非阻塞:非阻塞和阻塞的概念相对应,指在不能马上获得结果以前也会马上返回,同时该函数不会阻塞当前线程。web


 

同步与阻塞的区别:shell

首先,同步并非阻塞,对于同步调用来讲,不少时候当前线程仍是激活的,只是从逻辑上当前函数没有返回而已。例如:windows

1. 同步调用:apply一个累计1亿次的任务,该调用会一直等待,直到任务返回结果为止,但并未阻塞住(即使是被抢走cpu的执行权限,那也是处于就绪态);并发

2. 阻塞调用:当socket工做在阻塞模式的时候,若是没有数据的状况下调用recv函数,则当前线程就会被挂起,直到有数据为止。app

阻塞与非阻塞:异步

阻塞与非阻塞针对的是进程或线程,阻塞是当请求不能知足的时候就将进程挂起,而非阻塞则不会阻塞当前进程

进程

进程的建立

对于通用系统(跑不少应用程序),须要有系统运行过程当中建立或撤销进程的能力,主要分为4中形式建立新的进程

  1. 系统初始化(查看进程linux中用ps命令,windows中用任务管理器,前台进程负责与用户交互,后台运行的进程与用户无关,运行在后台而且只在须要时才唤醒的进程,称为守护进程,如电子邮件、web页面、新闻、打印)

  2. 一个进程在运行过程当中开启了子进程(如nginx开启多进程,os.fork,subprocess.Popen等)

  3. 用户的交互式请求,而建立一个新进程(如用户双击暴风影音)

  4. 一个批处理做业的初始化(只在大型机的批处理系统中应用)

不管哪种,新进程的建立都是由一个已经存在的进程执行了一个用于建立进程的系统调用而建立的:

  1. 在UNIX中该系统调用是:fork,fork会建立一个与父进程如出一辙的副本,两者有相同的存储映像、一样的环境字符串和一样的打开文件(在shell解释器进程中,执行一个命令就会建立一个子进程)

  2. 在windows中该系统调用是:CreateProcess,CreateProcess既处理进程的建立,也负责把正确的程序装入新进程。

关于建立的子进程,UNIX和windows

1.相同的是:进程建立后,父进程和子进程有各自不一样的地址空间(多道技术要求物理层面实现进程之间内存的隔离),任何一个进程的在其地址空间中的修改都不会影响到另一个进程。

2.不一样的是:在UNIX中,子进程的初始地址空间是父进程的一个副本,提示:子进程和父进程是能够有只读的共享内存区的。可是对于windows系统来讲,从一开始父进程与子进程的地址空间就是不一样的

进程的终止

  1. 正常退出(自愿,如用户点击交互式页面的叉号,或程序执行完毕调用发起系统调用正常退出,在linux中用exit,在windows中用ExitProcess)

  2. 出错退出(自愿,python a.py中a.py不存在)

  3. 严重错误(非自愿,执行非法指令,如引用不存在的内存,1/0等,能够捕捉异常,try...except...)

  4. 被其余进程杀死(非自愿,如kill -9)

进程的层次结构

不管UNIX仍是windows,进程只有一个父进程,不一样的是:

  1. 在UNIX中全部的进程,都是以init进程为根,组成树形结构。父子进程共同组成一个进程组,这样,当从键盘发出一个信号时,该信号被送给当前与键盘相关的进程组中的全部成员。

  2. 在windows中,没有进程层次的概念,全部的进程都是地位相同的,惟一相似于进程层次的暗示,是在建立进程时,父进程获得一个特别的令牌(称为句柄),该句柄能够用来控制子进程,可是父进程有权把该句柄传给其余子进程,这样就没有层次了。

进程的三种状态

僵尸进程和孤儿进程

僵尸进程:

定义:僵尸进程是为了让父进程知道子进程什么结束而保留下来的一些状态信息,保留原有pid直到父进程死亡(有害)

缘由:在unix/linux中,正常状况下子进程是经过父进程建立的,子进程在建立新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远没法预测子进程到底何时结束,若是子进程一结束就马上回收其所有资源,那么在父进程内将没法获取子进程的状态信息。子进程死掉之后不会把子进程全部的信息都清理掉,会清理一些内存空间等,可是会保留一些状态信息来告诉父进程本身的状态。

注意:全部进程都会经历僵尸进程,父进程死掉后会发起一个系统调用,调用wait/waitpid去回收僵尸进程,把全部僵尸儿子都回收

孤儿进程:

一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工做。

例子:

from multiprocessing import Process
import time,os

def task():
    print('%s is running' %os.getpid())
    time.sleep(3)
    
if __name__ == '__main__':
    p=Process(target=task)
    p.start()
    p.join() # 等待进程p结束后,join函数内部会发送系统调用wait,去告诉操做系统回收掉进程p的id号

    print(p.pid) #???此时可否看到子进程p的id号
    print('主')

#答案:能够
#分析:
p.join()是像操做系统发送请求,告知操做系统p的id号不须要再占用了,回收就能够,
此时在父进程内还能够看到p.pid,但此时的p.pid是一个无心义的id号,由于操做系统已经将该编号回收

进程详解python实现

http://www.javashuo.com/article/p-rzsppguf-c.html

线程详解python实现

http://www.javashuo.com/article/p-dflginxu-mp.html

协程:

http://www.javashuo.com/article/p-bhhuxkwh-p.html

IO模型:

http://www.cnblogs.com/linhaifeng/articles/7454717.html

总结:

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息