python多线程与多进程的区别是什么? (python量化交易框架)

python多线程与多进程的区别是什么? (python量化交易框架)

本文目录导航:

python多线程与多进程的区别是什么?

多线程与多进程是计算机程序运转时两种不同的并发模型。

构想一家忙碌的餐厅,用来解释它们的区别。

多进程就像餐厅开分店,每个店都有独立的服务员,各自独立运作,解决不同的顾客需求,相互不影响。

多线程则像是同一家餐厅,但多雇用服务员。

这些服务员共处一室,为同一餐厅服务,可以同时解决多份订单,提高效率。

在多线程中,还存在协程(异步)的概念,即服务员可以先解决下一份订单,直到上一份成功,以提高效率。

但是,假设餐厅外敷务员之间由于争夺资源(如出票机或操作屏)而相互阻遏,就或者造成线程死锁。

Python经过全局解释器锁(gil锁)来防止此类死锁,但这也限度了多线程在CPU密集型义务上的性能。

餐厅中的顾客寻觅服务员点餐,若多个顾客同时寻觅同一服务员,造成排队期待,即为阻塞形态。

异步复线程非阻塞形式准许餐厅在不期待的状况下,让多个顾客在不同期间段成功点餐,成功并发。

异步多线程非阻塞形式则经过多个服务员分工协作,雷同成功多个顾客不期待即可成功点餐,雷同成功并发。

同步多线程非阻塞形式则准许同时点餐,但须要服务员协调,以防止资源争夺。

复线程的餐厅不易产生相似死锁疑问。

了解了多线程与多进程的实质区别后,你曾经把握了Python并发编程的外围部分,可以开局通常了。

Python的多进程、多线程、协程 —— join的用法

Python的多进程、多线程、协程的探讨中,join这个关键字是经常被漠视的。

首先明白,进程与线程的区别在于进程共享内存,而线程共享进程的内存。

而协程则是一种轻量级的线程,更实用于管理流程的高低文。

在成功多线程时,join用于期待一个线程成功口头。

对比上方两段代码,可以看到join的差异。

代码1:线程串行口头,运转结果为16秒。

代码2:join确保一切线程口头,但实践运转结果并无并行成果,说明join的经常使用。

join配置的解释:当代码口头到线程的join时,主线程会卡住,直到该线程口头成功。

因此,经常使用join时,应选用最长口头期间的线程,缩小不用要的join重叠。

join的用途:在多线程爬虫场景下,主程序期待一切URL爬取成功后再启动数据解决。

假设不确定线程口头顺序,确保每个线程都口头join是正当的。

后记:了解并正确经常使用join是多线程编程的关键,以确保程序的正确性和效率。

python多进程为什么必定要

前面讲了为什么Python里介绍用多进程而不是多线程,但是多进程也有其自己的限度:相比线程愈加轻便、切换耗时更长,并且在python的多进程下,进程数量不介绍超越CPU外围数(一个进程只要一个GIL,所以一个进程只能跑满一个CPU),由于一个进程占用一个CPU时能充沛应用机器的性能,但是进程多了就会产生频繁的进程切换,反而得失相当。

不过不凡状况(特指IO密集型义务)下,多线程是比多进程好用的。

举个例子:给你200W条url,须要你把每个url对应的页面抓取保管起来,这种时刻,单单经常使用多进程,成果必需是很差的。

为什么呢看例如每次恳求的期待期间是2秒,那么如下(疏忽cpu计算期间):1、单进程+复线程:须要2秒*200W=400W秒==1111.11个小时==46.3天,这个速度显著是不能接受的2、单进程+多线程:例如咱们在这个进程中开了10个多线程,比1中能够优化10倍速度,也就是大概4.63天能够成功200W条抓取,请留意,这里的实践口头是:线程1遇见了阻塞,CPU切换到线程2去口头,遇见阻塞又切换到线程3等等,10个线程都阻塞后,这个进程就阻塞了,而直到某个线程阻塞成功后,这个进程能力继续口头,所以速度上优化大概能到10倍(这里疏忽了线程切换带来的开支,实践上的优化应该是不能到达10倍的),但是须要思考的是线程的切换也是有开支的,所以不能有限的启动多线程(开200W个线程必需是不靠谱的)3、多进程+多线程:这里就凶猛了,普通来说也有很多人用这个方法,多进程下,每个进程都能占一个cpu,而多线程从必定水平上绕过了阻塞的期待,所以比单进程下的多线程又更好使了,例如咱们开10个进程,每个进程里开20W个线程,口头的速度通常上是比单进程开200W个线程快10倍以上的(为什么是10倍以上而不是10倍,重要是cpu切换200W个线程的消耗必需比切换20W个进程大得多,思考到这部分开支,所以是10倍以上)。

还有更好的方法吗看答案是必需的,它就是:4、协程,经常使用它之前咱们先讲讲what/why/how(它是什么/为什么用它/怎样经常使用它)what:协程是一种用户级的轻量级线程。

协程领有自己的寄存器高低文和栈。

协程调度切换时,将寄存器高低文和栈保管到其余中央,在切回来的时刻,复原先前保管的寄存器高低文和栈。

因此:协程能保管上一次性调用时的形态(即一切部分形态的一个特定组合),每次环节重入时,就相当于进入上一次性调用的形态,换种说法:进入上一次性分开时所处逻辑流的位置。

在并发编程中,协程与线程相似,每个协程示意一个口头单元,有自己的本地数据,与其它协程共享全局数据和其它资源。

why:目前支谣言语基本上都选用了多线程作为并发设备,与线程关系的概念是抢占式多义务(Preemptive multitasking),而与协程关系的是协作式多义务。

不论是进程还是线程,每次阻塞、切换都须要堕入系统调用(system call),先让CPU跑操作系统的调度程序,而后再由调度程序选择该跑哪一个进程(线程)。

而且由于抢占式调度口头顺序不可确定的特点,经常使用线程时须要十分小心肠解决同步疑问,而协程齐全不存在这个疑问(事情驱动和异步程序也有雷同的好处)。

由于协程是用户自己来编写调度逻辑的,对CPU来说,协程其实是复线程,所以CPU不用去思考怎样调度、切换高低文,这就省去了CPU的切换开支,所以协程在必定水平上又好于多线程。

how:python外面怎样经常使用协程看答案是经常使用gevent,经常使用方法:看这里经常使用协程,可以不受线程开支的限度,我尝试过一次性把20W条url放在单进程的协程里口头,齐全没疑问。

所以最介绍的方法,是多进程+协程(可以看作是每个进程里都是复线程,而这个复线程是协程化的)多进程+协程下,避开了CPU切换的开支,又能把多个CPU充沛应用起来,这种形式关于数据量较大的爬虫还有文件读写之类的效率优化是渺小的。

小例子:#-*- coding=utf-8 -*-import requestsfrom multiprocessing import Processimport geventfrom gevent import monkey; _all()import sysreload(sys)(utf8)def fetch(url):try:s = ()r = (url,timeout=1)#在这里抓取页面except Exception,e:print ereturn def process_start(tasks)(tasks)#经常使用协程来口头def task_start(filepath,flag = ):#每10W条url启动一个进程with open(filepath,r) as reader:#从给定的文件中读取urlurl = ()()task_list = []#这个list用于寄存协程义务i = 0 #计数器,记载参与了多少个url到协程队列while url!=:i += 1task_((fetch,url,queue))#每次读取出url,将义务参与到协程队列if i == flag:#必定数量的url就启动一个进程并口头p = Process(target=process_start,args=(task_list,))()task_list = [] #重置协程队列i = 0 #重置计数器url = ()()if task_list not []:#若分开循环后义务队列里还有url残余p = Process(target=process_start,args=(task_list,))#把残余的url全都放到最后这个进程来口头()if __name__ == __main__:task_start(./)#读取指定文件认真的同窗会发现:上方的例子中暗藏了一个疑问:进程的数量会随着url数量的参与而始终参与,咱们在这里不经常使用进程池来管理进程数量的要素是和gevent有抵触不能同时经常使用,但是有兴味的同窗可以钻研一下这个协程池。

另外还有一个疑问:每个进程解决的url是累积的而不是独立的,例如第一个进程会解决10W个,第二个进程会变成20W个,以此类推。

最后定位到疑问是()造成的疑问,有兴味的同窗可以钻研一下为什么会这样。

不过这个疑问的解决打算是:主进程只担任读取url而后写入到list中,在创立子进程的时刻间接把list传给子进程,由子进程自己去构建协程。

这样就不会产生累加的疑问

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

31阅读

外国教程python,python编程教学视频

2026年09月02日

25阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

21阅读

python库包教程,python 包

2026年09月02日

27阅读

python教程大全集,python教程600集

2026年09月02日

26阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

22阅读