当前位置: 首页 > 网络应用技术

Python线程合适多少

时间:2023-03-07 19:42:26 网络应用技术

  简介:许多朋友询问Python线程合适的多少。本文的首席CTO注释将为您提供详细的答案,以供您参考。我希望这对每个人都会有所帮助!让我们一起看看!

  最近,我正在做一个相关的项目。整个电线的整个电台爬网确实不大,而且也厌倦了一次跑步。在这里有几个主要问题(关于Python的python多线程的吉尔问题,都不再提及,有几个主要问题在线太多)。

  首先,由于多线程可以缩短程序的运行时间,因此线程数量越大,越好?

  显然,每个线程都不是世代相传的。太多的线程会占用太多的系统资源(内存开销,CPU开销),并且生成太多线程时间是相当多的。这是最佳线程数量的计算方法:

  获得最佳线程号:

  1.慢慢通过用户增加性能压力测试,观察QPS(即每秒响应请求的数量,即最大吞吐量。),响应时间

  2.根据公式计算:服务器端的最佳线程号=((线程等待时间+线程CPU时间)/线程CPU时间) * CPU数量

  3.单用户压力测试,检查CPU消耗,然后直接乘以百分比,然后执行压力测试。通常,最好的线程接近该值的值。

  2.为什么要使用线程池?

  对于任务数量不断增加的过程,每个任务都会生成一个线程,这最终将导致线程数的失控。获取此链接对应于相应页面上的新链接。作为一项新任务,目前必须为这些新链接生成新线程,并且线程数量飙升。在后续操作中,线程数将继续增加,并且无法完全控制。对于增加任务数量的过程,需要一个带有许多固定线程的线程池。

  如何使用线程池

  过去,使用了螺纹池模块,现在使用并发模块通常使用。该模块是Python3随附的模块。但是,也可以安装和使用Python2.7的版本。

  注意:

  conturrent.futures.threadpoolexecutor,在提交任务时,有两种方法是cumber()函数,另一个是map()函数。两者之间的主要区别是:

  如果未执行Python多线程的数量,则在一定程度上,在一定程度的启动线程后,启动线程的数量将不正确。

  有几分钟来控制多线程的并发症的数量。以下介绍了控制多线程并发症的并发症与queue.python3的方法的方法

  由于Python具有GIL全球解释器锁,Python的多线多核心,但是如果它是一个IO -dense项目,那么多线程效率也非常好。我使用多线程来制作爬网。

  由于python的臭名昭著的吉尔。

  那吉尔是什么?为什么有吉尔?多线程真的是鸡排吗?可以去除吉尔吗?如果有这些问题,我们在一起看着,同时需要一点耐心。

  是多线鸡肋骨吗?让我们先进行实验。实验非常简单。它是为了减少“ 1亿”的数量,并将其减少到0程序。如果我们使用单个线程执行,那么完成时间是什么?将使用多线程?显示我的代码

  单线

  在我的4台CPU计算机中,在单个线程上花费的时间为6.5秒。有人可能会问,线程在哪里?实际上,当任何程序运行时,默认情况下将有一个主线程执行。(关于线程和过程不会在这里扩展,我将分别打开一篇文章)

  多线程

  创建两个子线程T1和T2,每个线程执行5000万次执行,并且在执行两个线程后,主线程终止程序操作。结果,在合作中执行了两个线程,但合作执行了6.8秒,但放慢了速度从理论上讲,这两个线程同时在两个CPU上运行。时间应该减半,但现在没有减少。

  是什么导致多线程不现实和缓慢?

  原因在于吉尔。在Cpython解释器(Python语言中的主流解释器)中,有一个全局的解释锁。当解释器解释Python代码时,这意味着该锁首先意味着任何时间,可能只有一个线程执行代码。如果其他线程想获得CPU执行代码指令,则必须先获得此锁定。如果锁被其他线程占据,则线程只能等到锁的线程被锁的线占据,释放锁可能会执行代码指令。

  因此,这就是为什么两个线程在一起慢的原因,因为同时,只有一个线程正在运行,而其他线程只能等待。即使是多核CPU也可以在同一Timethe执行代码上同时使用多个线程“并行”,因为多线程切换和锁定机制处理(获取锁,释放锁等),因此可以交替执行。参与其中,因此多线程执行不是快速且缓慢。

  吉尔什么时候发布?

  当线程遇到I/O任务时,将发布GIL。当CPU结合线程执行100个口译器(ticks)(ticks)(ticks)(ticks)(可以大致认为是Python虚拟机)时,GIL也将是发布。您可以通过设置步骤长度来检查步骤的步骤。

  为什么Cpython的解释器设计这样?

  多线程是适应现代计算机硬件的高速开发,以充分利用多核处理器的产品。通过多线程,可以有效地使用CPU资源。Python出生于1991年。在Timethe Server 32 Core 64g内存并不常见

  但是,多线程存在问题。如何解决共享数据的同步和一致性问题,因为当多个线程访问和共享数据时,可能会有两个线程同时修改一个数据情况。如果没有合适的机制来确保Dathathen的一致性最终导致异常,因此Python的父亲具有全球线锁。无论您是否与数据有同步问题,无论如何,您都可以将其切成全局锁以确保数据安全性。这是多线程鸡排的原因,因为它没有对安全性的良好的控制数据,但以简单而粗鲁的方式解决。

  该解决方案放置在1990年代。实际上,没有问题。毕竟,当时的硬件配置仍然非常简单。单个核心CPU仍然是主流。run,不涉及线程的上下文切换,但是效率高于多线程(在多核环境中,此规则不适用)。因此,它不适用使用GIL确保数据的一致性和安全性所必需。至少在当时这是一种非常低的成本实施方法。

  删除吉尔是否可行?

  有人确实做了很多事情,但结果令人失望。1999年,两个伙伴格雷格·斯坦(Greg Stein)和马克·哈蒙德(Mark Hammond)创建了一个python分支,该分支将吉尔(Gil)删除并用更可变的数据结构取代了更细腻的数据结构。在单线条件下,Python的速度速度较慢。

  Python的父亲说:基于上述考虑,GIL在不必花费太多精力的情况下没有很大的价值。

  在实际的处理数据中,由于系统内存有限,我们无法一次导出所有数据,因此我们需要按批处理导出。为了加快操作,我们将使用多线程方法进行数据处理。

  主要分为三个部分:

  总共4个部分总结了多线程内容。

  让我首先介绍该线程的相关概念:

  在超速节目中,如果没有多线程,我们将在听歌曲,听歌曲和玩游戏的同时演奏速度,这是无法平行的。使用多线程后,我们可以在玩游戏时收听背景音乐。在此示例中,启动超速程序是一个过程。玩游戏和听音乐是两个线程。

  Python提供了实现多线程的线程模块:

  因为新线程系统需要分配资源,并且线程系统的终止需要回收资源,因此,如果可以重复使用线程,则可以减少新构建/终止费用以提高性能。在同一时间,线程池的语法为比新线程执行线程更简洁。

  Python为我们提供了ThreadPoolExecutor来实现线程池,这在此线程池中是防御性的。它的适应场景是大量突然的请求,或者需要大量线程来完成任务,但是实际的任务处理时间很短。

  MAX_WORKER是线程池中的线程数。常用的遍历方法包括地图和提交+as_completed.cording。根据不同的业务方案,如果我们需要按遍历的顺序返回输出结果,我们将使用地图方法。如果我们想先完成谁,我们将使用cumber+as_complete方法。

  我们将在一段时间内使用的一个线程称为关键资源,必须执行对关键资源的访问。Mutual排除,也称为间接限制。线程相互谴责意味着,当线程访问关键资源时,其他想要访问关键资源的线程必须等待。当前对关键资源的访问已经结束,并且在发布资源后,另一个线程可以访问关键资源。锁的功能是实现相互拒绝线程的函数。

  我把线路放到厕所私人房间的大型过程中,因为私人房间里只有一个坑,所以只有一个人可以进行大尺寸。当第一个人想去厕所时,门将被锁定。目前,如果第二个人也想大大,则必须完成第一人称,并且可以继续进行锁。在此期间,两者只能在门外等待。此过程与使用代码中使用锁定的原理完全相同。这里的坑是关键资源。Python的线程模块引入了锁。线程模块提供了一个锁类,该类具有以下方法锁定和释放锁:

  我们会发现该程序只会打印“第一个锁”,并且该程序既不会终止也不继续运行。执行,这使得无法执行版本,因此锁定永远无法释放。这是僵局。如果我们使用RLOCK正常运行,就不会发生僵局。

  定义主线程中的锁定锁,然后锁定,然后创建一个子线程t运行主函数以释放锁定。

  如果将上述锁更改为RLOCK,则报告了一个错误。设计程序时,我们将将每个功能封装到一个函数中,并且每个功能中可能存在关键区域,因此需要RLOCK。

  总之,无法打包锁,可以设置RLOCK;锁可以由其他线程中的锁操作,而Rlock只能由该线程操作。

  在Python中使用线程模块可以运行程序的不同部分并简化设计。如果您已经启动Python并想使用线程来提高程序的速度,我希望本教程对您有帮助。

  线程和过程

  什么是一个过程

  该过程是系统地执行资源分配和调度的独立单元流程。这是一个有关数据集上运行活动的独立功能的过程。该过程是执行资源分配和调度的系统的独立单元。east过程具有其独立的内存空间,并且通过Inter -Process通信进行了不同的过程。由于该过程相对较重,并且占据了独立的内存,因此Switching Switching Switch intering在头顶上开发(堆栈,注册,虚拟内存,文件句柄等)上下文过程之间相对较大,但相对稳定且安全。

  什么是线程

  CPU调度和分发的基本单元线程是该过程的实体,即CPU调度和分发的基本单元。它是一个基本单元,可以比该过程更独立地运行。它是操作中的重要资源(例如程序计数器,一组寄存器和堆栈),但它可以共享由同一流程所拥有的所有资源到相同的过程。线程之间的通信主要通过共享内存。上下文切换很快,资源开销很小,但是与过程相比,数据容易丢失数据。

  过程与线程之间的关系

  线程和过程之间的区别:

  过程

  在现实生活中,场景中有很多事情同时进行。例如,当您开车时,您可以一起驾驶汽车和脚。

  注意:

  概念概念

  什么是多个任务?简而言之,操作系统可以同时运行多个任务。例如,当您使用浏览器在互联网上浏览Internet时,在收听MP3时,您正在使用Word来快点。这是多任务处理。至少有3个任务正在同一时间运行。在后台同时同时安静地运行了许多任务,但是桌面上没有显示。

  目前,多核CPU非常受欢迎,但是即使在过去的单核CPU中,也可以执行多个任务。由于CPU执行代码是按顺序执行的。

  答案是,操作系统需要轮流以交替执行每个任务。任务1执行0.01秒,切换到任务2,任务2执行0.01秒,然后切换到任务3,然后执行0.01秒。这是反复执行的。在表面上,每个任务都交替执行,但是由于CPU的执行速度太快,我们认为所有任务均同时执行。

  实际并行执行多任务只能在多核CPU上实现。但是,由于任务的数量远远超过CPU的核心数量,因此操作系统将自动将许多任务派遣到每个核心以进行执行。实际上,CPU执行速度太快了!动荡的安排。

  平行和并发

  并行性

  并行:同时指的是两个或多个事件(或线程),同时,在实际意义上同时在不同的CPU资源上同时(Multi -core),不同的事件或线程,并同时执行。

  特征

  并发

  在几个渠道程序(或线程)之间以多种原因指出物理CPU(也是多个物理CPU),并且该公司被迫行使多用户共享以提高物理资源以提高效率。

  特征

  Multiprocess.prcess模块

  该过程模块是创建过程的模块。使用此模块,可以完成该过程的创建。

  

  该类别获得的对象指示子过程中的任务(未启动)。

  注意:1。必须使用关键字方法来指定参数;2. ARGS指定传递给目标函数的位置参数。这是一种正式的祖先形式,必须具有逗号。

  参数简介:

  组:未使用参数,默认值无。

  目标:表示子过程要执行的任务。

  args:指示呼叫的位置参数。

  Kwargs:指示呼叫对象的字典。例如kwargs = {'name':jack,'age':18}。

  名称:子过程名称。

  代码:

  除了上述打开该过程的方法外,还可以通过继承该过程来启动该过程:

  通过上述研究,我们尽了最大的努力来实现该程序的异步,因此可以在多个过程中处理多个任务。他们之间的操作没有订单,一旦打开,它就不会由我们控制。尽管并发编程使我们能够完全使用IO资源,但它也带来了我们的新问题。

  当多个进程使用相同的数据资源时,它将导致数据安全性或顺序混淆。我们可以考虑锁定。我们以模拟票证抓取作为示例,以查看数据安全的重要性。

  当锁定可以确保多个进程修改相同的数据时,只能同时修改一个任务,即串行修改。

  因此,我们最好找到一个解决方案以考虑到这两者:1。高效率(多个过程共享一个内存数据)2。帮助我们解决锁定问题。

  由MutiProcessing模块提供的基于消息的IPC通信机制:队列和管道。队列和管道是根据(管道+锁)实现的,以将数据存储在内存中,这可以使我们摆脱复杂的锁定问题。我们应该尝试避免使用共享数据,使用消息传输和排队尽可能多,排队队列,避免处理复杂的同步和锁定问题,以及当过程数量增加时,通常可以获得更好的展览性(随后的扩展。这个内容)。

  线

  Python的线程模块

  Python为多线程编程提供了几个模块,包括线程,线程和队列。线程和线程模块允许程序员创建和管理线程。线程模块提供基本的线程和锁定支持,并且线程提供更高的级别,更具功能性的线程管理功能。队列模块允许用户创建一个队列数据结构,该结构可用于在多个线程之间共享数据。

  Python创建和执行线程

  创建线程代码

  1.创建方法1:

  2.创建方法2:

  流程和线程是实现多个任务的一种方法,例如:多个QQ(进程)可以同时在同一台计算机上运行,并且一个QQ可以打开多个聊天窗口(线程)。回库共享:该过程不能为共享,使用线程共享过程的地址空间和其他资源。同时,该线程具有自己的堆栈和堆栈指针。因此,过程中的所有线程共享全局变量,但是通过多线程进行的全局变量的变化可能会导致变量混淆。

  代码演示:

  结果是:

  需要清楚的第一件事是,吉尔不是python的特征。这是实现Python Parser(CPYTHON)时引入的概念。就像C ++是一组语言(语法)标准,但可以通过不同的编译器将其编译到可执行的代码中。可以通过不同的Python执行相同的代码执行环境,例如cpython,pypy,psyco(jpython中没有吉尔(Jpython)的吉尔(Jpython)。

  那么Cpython实施中的GIL是什么?吉尔的全名全球口译员锁以避免误导,让我们看一下官方解释:

  主要含义是:

  因此,解释器实际上受到全局解释器锁的保护,它可以确保任何时候只有一个python线程。在多线程环境中,python虚拟机被执行如下:

  由于GIL的存在,Python的多线程不能称为严格的多线程。由于在执行多个线程期间,每个线程都需要首先获得GIL,因此可以保证只有一个线程同时运行。

  由于GIL的存在,即使它是多线程,实际上,同一时间也只有一个线程。由于此多线程线程的工作效率与单个线程不同,为什么您仍然需要使用多线程?

  由于先前的计算机基本上是单个核心CPU,因此多线程和单线线程几乎看不到差异。但是,由于计算机的快速开发,计算机几乎是所有多核CPU,至少是两个内核。目前,差异是差异。目前,差异是差异。它出现了:通过以前的情况,我们已经知道,即使在多核CPU中,多线程线程也只有一个线程。这不仅不能使用多核CPU的优势,而且由于在多个CPUSE上的多个CPU上都在多个CPU上交替使用多个CPU,因此在打开不同的CPU时会导致浪费资源。锁定一个过程。当执行多个线程时,GIL锁将在内部加扰,这将导致CPU在未抓取某个线程时等待,然后不能合理使用多核。CPU资源。

  但是,当使用多线程捕获网页的内容时,遇到IO阻塞时,该线程将临时释放GIL锁。目前,其他线程将使用此差距时间来执行自己的代码。因此,grassing性能很好,因此我们仍然需要使用多线程。

  吉尔对多载计划的影响

  该程序的性能受到计算的致密类型(CPU)和I/O -dense程序限制的过程限制的影响。那么,计算密集和i/o浓度程序是什么?

  计算致密类型:大量数值计算,例如数亿个数字计算,计算外围率,视频的高定义解码等等。主要时间在任务切换时期花费。目前,CPU执行任务相对较低。

  IO密集型类型:涉及网络请求(time.sleep())和磁盘IO任务是IO密集型任务。此类任务的特征是CPU消耗量,大多数任务都在等待IO操作(因为IO的速度远低于CPU和内存的速度)。对于IO强度,任务越多,越高,越高CPU效率,但也有一个极限。

  当然,为了防止GIL影响我们的程序,我们也可以使用线程锁。

  Lockrlock

  公共资源共享锁定机制:锁,RLOCK,SEMPHORE,状况等,只需为每个人共享锁和RLOCK。

  锁

  特征是执行速度很慢,但是保证了数据的安全性

  Rlock

  不当使用锁定代码将产生死锁。

  什么是死锁

  死锁:当线A持有独家锁A并尝试获得独家锁B时,线程B持有独家锁B并试图获得独家锁A.与另一方所需的锁以及发生的阻塞现象,我们称其为致命。也就是说,死锁指的是由于竞争资源而导致的多个过程造成的僵局。如果没有外力,这些过程将无法向前发展。

  因此,请注意如何在系统设计和过程计划方面预防这四个必要条件,即如何确定资源的合理分配算法以避免永久占据系统资源。

  僵局代码

  python线程交流

  如果每个线程都完成,则不需要通信,并且此代码非常简单。但这通常是不可能的。至少线程应与主线程通信,否则无法检索计算结果的内容。实际情况非常复杂,需要交换多个线程以获得正确的执行结果。

  Python中的队列是提供线路通信机制的消息队列。Python3被命名为队列,队列模块下提供了几个阻止队列。这些队列主要用于实现线程通信。

  在队列模块下,主要提供三个类别,代表三个队列。它们之间的主要区别是队列和队列的差异。

  简单的代码演示

  目前,代码将被阻止,因为队列中的内容已满。目前,您可以在第四个队列后面添加超时。put('苹果'),并且将其变为Queue.put('Apple',超时= 1),如果您等待1秒钟,铃铛仍然已满,并且会抛出例外并可以捕获异常。

  以同样的方式,如果队列为空,则默认情况下将被阻止。如果不阻止它,则可以使用queue.get_nowait()。

  掌握了队列阻止队列的特征后,您可以使用队列在以下程序中实现线程通信。

  以下证明了生产者和消费者。当然

  使用队列模块在线程之间进行通信并确保线程安全性。

  Coroutine

  理事会,也称为Micro -thread,纤维。英语名称Coroutine。

  Coroutine是在Python中实现多个任务的另一种方法,但是它占用比线程较小的执行单元(理解为必要的资源)。为什么它是执行单元,因为它具有CPU上下文。在合适的时间,我们可以将一个Coroutine切换到另一个Coroutine。

  大众理解:在一个线程中的一个函数中,您可以在任何地方保存一些当前功能的临时变量和其他信息,然后切换到另一个函数以执行。请注意,这不是通过调用功能和切换来完成的。开发人员本身切换原始功能的次数和何时。

  当实现多任务时,线程切换比从系统级别中保存和恢复CPU上下文要简单得多。操作系统具有CACH和其他数据,以供程序操作效率。操作系统还将帮助您完成这些数据的恢复操作。因此,线程的切换非常消耗。但是,Coroutine的切换仅仅是CPU的上下文,因此在第二秒内切换数百万个系统具有抗性。

  Greenlet和Gevent

  为了更好地使用Coroutine来完成多任务处理,除了使用本机产量完成模拟Coroutine的工作外,实际上,Greenlet模块和Python的Gevent模块也使Coroutine的实现更加多简单有效。

  尽管Greenlet实现了Coroutine,但它要求我们手工切换。这太麻烦了。Gevent是一个比Greenlet强大的模块,可以自动切换任务。

  原则是当绿色遇到IO(参考输入输出输入和输出,例如网络,文件操作等)操作(例如访问网络),自动切换到其他绿色,等待直到IO操作完成,然后在适当的时代开关继续执行。

  仿真时间 - 耗费操作:

  如果您还可以用时间耗费的操作替换它,则目前需要修补GEVENT中实现的模块。

  使用简单的第二手房屋信息的校正来使用校正!

  以下文章来自Python专栏,作者歌曲和歌曲

  文章链接:

  结论:以上是首席CTO注释为每个人编译的Python线程的相关内容的适当内容。希望它对您有所帮助!如果您解决了问题,请与更多关心此问题的朋友分享?