简介:许多朋友询问与Python的多线程线程有关的有多少个问题。本文的首席CTO笔记开始为您的参考做出详细的答案。我希望这对每个人都会有所帮助!让我们一起看看!
好的。
Python多线程
多线程类似于同时执行多个不同程序。多线程具有以下优点:
使用线程可以将任务放在延长的程序中,以应对。
用户界面可能更具吸引力。例如,如果用户单击按钮触发某些事件的处理,则可以弹出进度条以显示处理进度
程序的运行速度可能会加速
在某些等待的任务中,例如用户输入,文件读取和写作以及网络接收数据,线程更有用。在这种情况下,我们可以发布一些宝贵的资源,例如内存职业等。
线程与执行过程中的过程仍然不同。每个独立进程具有程序的入口,序列执行序列和程序的退出。申请的应用。
每个线程都有自己的一组CPU寄存器,称为线程的上下文。上下文反映了上次运行该线程的CPU寄存器的状态。
指令指针和堆栈指针寄存器是线程上下文中最重要的两个寄存器。线程始终在上下文中运行。这些地址用于在线程的过程地址空间中签名内存。
线程可以扣押(中断)。
当其他线程运行时,线程可以暂时搁置(也称为睡眠) - 这是线程的特许权。
python multi -process,同一时间,有几个线程运行
通常是一个,因为没有真实的多线程线程,但是在多线程中很快切换
如前所述,为什么建议使用Python使用多流程而不是多线程,但是多过程也有其自己的限制:与线程更大和切换时间相比,在Python的多过程中,流程的数量不建议超过CPuthe核心号(一个过程仅一个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次),但是有必要考虑切换的切换该线程也可以预期,因此有一个开销,Socan不会启动多线程(200W线程绝对不可靠)
3. Multi -Processes+Multi -threads:在这里真是太神奇了。一般而言,许多人使用这种方法。在多进程下,每个过程都可以占据CPU,并且多线程螺纹绕过等待在一定程度上的阻塞。因此,它比单个过程中的多线程线更好。例如,我们在每个过程中打开10个过程和20W线程。它是10次以上,而不是10次,主要是因为CPU开关200W线程消耗绝对比20W过程大得多,考虑到这部分费用,因此它超过10次)。
有更好的方法吗?答案是肯定的,是:
4.理事会,让我们谈谈在使用它之前什么/为什么/如何/为什么/为什么使用它/如何使用它)
什么:
理事会是一个用户级别的轻量级线程。Coroutine具有自己的寄存器上下文并堆叠。当Coroutine调度和切换时,将寄存器上下文保存并堆叠到其他地方。缩短时,还原先前保存的寄存器上下文并堆栈。
Coroutine可以保留先前呼叫的状态(即所有当地状态的特定组合)。每次重新输入该过程时,它等同于输入最后一个呼叫的状态。
在并发编程中,Coroutine类似于线程。每个Coroutine代表一个具有自己本地数据的执行单元,并与其他Coroutines共享全局数据和其他资源。
FAL:
目前,主流语言基本上选择了多线程作为并发设施。线程相关概念的概念是抓住Premptive多任务处理,而协作多任务与Coroutine有关。
无论是过程还是线程,每次被阻止或切换时,都需要在系统调用(系统调用)中捕获,首先让CPU运行操作系统调度程序,然后计划计划程序决定哪个过程(线程)应运行。
而且,由于夺取计划执行的顺序的特征,在使用线程时,有必要非常仔细地处理同步问题,并且根本没有这样的问题(事件驱动程序和异步程序具有相同的优势)。
因为Coroutine是用户本身编写调度逻辑的用户,因此对于CPU,Coroutine实际上是一个线程,因此CPU无需考虑如何安排,切换上下文,这消除了CPU切换在上面的上空,因此在确定性上可以肯定的是,它比多线程更好。
如何:
如何在Python中使用Coroutines?答案是使用Gevent,如何使用:请参阅此处
使用公司不能受到线程开销的限制。我试图一次将20W URL放入一次过程中。这完全很好。
因此,最建议的方法是多进程+coroutine(可以在每个过程中视为单个线程,并且该单个线程被纠正)
在多个流程+Coroutines下,CPU开关开销已被避免,并且可以使用多个CPU来充分利用它。对于具有大量数据和文件读写的爬行动物的效率,此方法是巨大的。
尖端:
[python]查看普通副本
# - * - 编码= UTF-8 - * -
导入请求
从多处理导入过程
进口Gevent
来自Gevent Import Monkey;monkey.patch_all()
导入系统
重新加载(系统)
sys.setdefaultencoding('utf8')
def提取(url):
尝试:
s = requests.session()
r = s.get(url,timeout = 1)#在这里抓取页面
除例外,E:
打印e
返回 '??'
def Process_start(url_list):
任务= []
对于URL_LIST中的URL:
tasks.append(gevent.spawn(fetch,url))
gevent.joinall(任务)#use coroutine执行
def task_start(filepath,flag = 100000):#启动每个10W URL的进程
使用开放(filepath,'r')作为读取器:##从给定文件中读取URL
url = reader.readline()。条 ()
url_list = []#该列表用于存储公司任务
i = 0#计数器,在公司队列中添加了多少个URL
url!='':
i+= 1
url_list.append(url)#each阅读URL,将URL添加到队列中
如果i == flag:#a某些URL数量启动一个进程并执行
p = process(target = process_start,args =(url_list,))
p.start()
url_list = [] #reset url队列
i = 0#重置计数器
url = reader.readline()。条 ()
如果url_list不[]:#如果您退出循环,则在任务队列中仍然有URL的剩余
p = process(target = process_start,args =(url_list,))#
p.start()
如果__name__ =='__ main __':
task_start('https://www.shouxicto.com/article/testdata.txt')
仔细的同学会发现上面的示例隐藏了一个问题:随着URL数量的增加,过程的数量将继续增加。我们不使用流程池多处理。池在这里控制过程的数量。气味有冲突,不能同时使用,但是感兴趣的学生可以研究gevent.pool coroutine pool。
共有20个线程
如果执行订单,它可能会互相交叉,并且不得按顺序执行
还要注意Python的线程有时称为伪线
什么,Python线程太慢,想使用Greenlet,快速,很方便编写。
如果锁同步,则可以减慢线程。
ulimit -s返回线程堆栈的大小,我的默认值为8192,并且通过删除内存的大小来获得线程的理论数。
如果未执行Python多线程的数量,则在一定程度上,在一定程度的启动线程后,启动线程的数量将不正确。
有几分钟来控制多线程的并发症的数量。以下介绍了控制多线程并发症的并发症与queue.python3的方法的方法
结论:以上是首席执行官注释编写的Python多线多线的内容。感谢您花时间阅读此网站。我希望这对您有帮助。更多关于可以在此站点上找到多少python多线程。