2016 - 2024

感恩一路有你

python如何判断远程文件是否存在 Python多进程和多线程是鸡肋嘛?

浏览量:2009 时间:2023-06-03 10:06:37 作者:采采

Python多进程和多线程是鸡肋嘛?

GIL的存在一直备受争议,这使得Python程序无法真正利用现代操作系统的多进程特性。需要注意的是,I/O图形处理和NumPy数学计算等耗时的操作都发生在GIL之外,基本上不受影响。真正受影响的是Python字节码的执行,GIL会导致性能瓶颈。简而言之,只有当纯Python用于CPU密集型多线程时,GIL才会成为问题。

什么是GIL?Python s代码执行由Python虚拟机控制(也叫解释器主循环,CPython版本)。Python最初被设计成只有一个线程在解释器主循环中运行。也就是说,每个CPU在任何时候都只有一个线程在解释器中运行。对Python虚拟机的访问由全局解释锁GIL控制,它控制一次只能运行一个线程。-单核CPU下的多线程其实是并发的,不是并行的。

并发和并行的区别

并发性:两个或多个事件在同一时间间隔内发生,或者交替做不同的事件,或者交替执行不同的代码块的能力。并行性:两个或多个事件同时发生,或者同时执行不同事件,或者同时执行不同代码块的能力。

并发和并行的含义

并发和并行都可以处理 "多任务 ",两者的主要区别在于多任务是否 "同时进行 "。但是涉及到任务分解(有顺序依赖耦合度高的任务不能并行)、任务操作(互斥、加锁、共享等。),以及结果合并。

Python中的多线程在Python多线程下,每个线程的执行模式如下:

有两种机制可以获得GIL并切换到这个线程来执行正在运行的代码:指定数量的字节码指令(100)和15毫秒的固定时间。线程主动放弃控制,并将线程设置为睡眠状态以释放GIL。再次重复上述步骤。在Python2中,当解释器解释任何Python代码的执行时,都需要先获得这个锁(只有一个获得了GIL的线程在同时运行,其他所有线程都在等待GIL发布)。如果是没有I/O操作的纯计算程序,解释器会每100次操作释放一次锁,让其他线程有机会执行(这个数字可以通过调整)。正是这样的设定,多线程CPU密集型计算显得很鸡肋,下面就说说为什么。

在python3中,GIL不使用滴答来计数(100次,释放GIL),而是使用定时器来代替(执行时间达到15ms阈值后,当前线程释放。放GIL),使得计算次数更多,释放次数更少,对CPU密集型程序更友好,但还是没有解决GIL一次只能执行一个线程的问题,所以效率还是不尽如人意。

Python s多线程一个鸡肋?CPU密集型(各种循环处理,计数等。),在这种情况下,滴答数很快就会达到阈值,然后触发GIL的释放和重新竞争(多线程来回切换需要资源),所以python中的多线程对CPU密集型代码并不友好,会触发相当频繁的线程切换。

IO密集型(文件处理、网络爬虫等。),多线程可以有效提高效率(如果单线程下有IO操作,就会等待IO,造成不必要的时间浪费,而开启多线程可以在线程A等待的同时自动切换到线程B,不会浪费CPU资源,从而提高程序执行效率。一个线程从GIL获得一个消息,然后等待返回消息(阻塞),Python在这个时候释放GIL。其他线程得到GIL发送的消息,然后等待返回消息(阻塞)........................................................................................................................................................所以python 的多线程对IO密集型代码很友好。

结论是什么?I/O密集型使用多线程并发执行提高效率,计算密集型使用多处理并行执行提高效率。通常程序中既包含IO操作,又包含计算操作,所以这种情况下,在开始并发任务之前,可以先测试一下,测试一下多线程多进程哪种方法效率高。

请注意:多核多线程比单核多线程差。多核多进程下,CPU1释放GIL后,其他CPU上的线程会竞争,但GIL可能马上被CPU1拿走。CPU2释放GIL后,其他CPU上被唤醒的线程会被唤醒,等待切换时间后再进入待调度状态,这样会导致线程抖动,效率降低。

多线程下的CPU密集型计算并非不可救药。ctypes可以绕过GIL,让py直接调用C动态库的任何导出函数。我们要做的就是用C/C把关键部分写成Python扩展,而且ctypes会在调用C函数之前释放GIL。

同时可以了解下一个进程,也就是微线程。

协成最大的优势就是极高的执行效率。因为子程序切换不是线程切换,而是由程序本身控制,所以没有线程切换的开销。与多线程相比,线程越多,协程的性能优势就越明显。

第二个优点是不需要多线程锁定机制,因为只有一个线程,不存在同时写变量的,共享资源在进程中不加锁控制,只是判断状态,所以执行效率比多线程高很多。

因为进程是一个线程执行的,如何使用多核CPU?最简单的方法就是多进程协调,既充分利用了多核,又充分发挥了协调的高效率,可以获得极高的性能。

python webservice服务接口参数?

传递对象参数(方法1)

通过查看远程方法,发现fun接口的参数类型是paramType,它有两个属性,P1和P2。

客户端客户端(url)

(参数类型)

m.p1

GIL 线程 多线程 Python 进程

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。