python多线程并发

python线程信号量semaphore(33)

强颜欢笑 提交于 2019-12-06 04:21:31
通过前面对 线程互斥锁lock / 线程事件event / 线程条件变量condition / 线程定时器timer 的讲解,相信你对线程threading模块已经有了一定的了解,同时执行多个线程的确可以提高程序的效率,但是并非线程的数量越多越好,可能对于计算机而言,你直接运行20~30线程可能没太大影响,如果同时运行上千个甚至上万个呢?我相信你电脑会直接瘫痪…… 一.semaphore信号量原理 多线程同时运行,能提高程序的运行效率,但是并非线程越多越好,而semaphore信号量可以通过内置计数器来控制同时运行线程的数量,启动线程(消耗信号量)内置计数器会自动减一,线程结束(释放信号量)内置计数器会自动加一;内置计数器为零,启动线程会阻塞,直到有本线程结束或者其他线程结束为止; 二.semaphore信号量相关函数介绍 acquire() — 消耗信号量,内置计数器减一; release() — 释放信号量,内置计数器加一; 在semaphore信号量有一个内置计数器,控制线程的数量,acquire()会消耗信号量,计数器会自动减一;release()会释放信号量,计数器会自动加一;当计数器为零时,acquire()调用被阻塞,直到release()释放信号量为止。 三.semaphore信号量使用 创建多个线程,限制同一时间最多运行5个线程,示例代码如下: # !usr

python 高性能编程之协程

拟墨画扇 提交于 2019-12-06 01:03:16
用 greenlet 协程处理异步事件 自从 PyCon 2011 协程成为热点话题以来,我一直对此有着浓厚的兴趣。为了异步,我们曾使用多线程编程。然而线程在有着 GIL 的 Python 中带来的性能瓶颈和多线程编程的高出错风险,“协程 + 多进程”的组合渐渐被认为是未来发展的方向。技术容易更新,思维转变却需要一个过渡。我之前在异步事件处理方面已经习惯了回调 + 多线程的思维方式,转换到协程还非常的不适应。这几天我非常艰难地查阅了一些资料并思考,得出了一个可能并不可靠的总结。尽管这个总结的可靠性很值得怀疑,但是我还是决定记录下来,因为我觉得既然是学习者,就不应该怕无知。如果读者发现我的看法有偏差并指出来,我将非常感激。 多线程下异步编程的方式 线程的出现,为开发者带来了除多进程之外另一种实现并发的方式。比起多进程,多线程有另一些优势,比如可以访问进程内的变量,也就是共享资源。还有的说法说线程创建比进程创建开销低,考虑到这个问题在 Windows 一类进程创建机制很蹩脚的系统才存在,故先忽略。总的来说,线程除了可以实现进程实现的“并发执行”之外,还有另一个功能,就是管理应用程序内部的“事件”。我不知道把这种事件处理分类到异步中是不是合适,但事件处理一定是基于共享进程内资源才能实现的,所以这是多线程可以做到而多进程做不到的一点。 异步处理基于两个前提。第一个前提是支持并发

Python面试题(4)

浪子不回头ぞ 提交于 2019-12-06 00:37:25
1.Python下多线程的限制以及多进程中传递参数的方式 Python多线程有个全局解释器锁,这个锁的意思是任一时间只能有一个线程运用解释器。并发不是并行。 多进程间同享数据,能够运用multiprocession.Value和multiprocessing.Array 认真学习下multiprocessing模块 2.Python是怎样进行内存管理的 内存池的概念 3.什么是lambda函数?他有什么好处? lambda函数是一个能接纳任意多个参数并且返回单个表达式值的函数。 lambda函数不能包括指令,他们所包括的表达式不能超过一个。 不要试图想lambda函数中塞入太多东西,如果需要更复杂的东西,就定义一个一般函数。 4.怎么用Python输出一个Fibonacci数列? 基础。 5.介绍下Python中webbrowser的用法? 熟悉webbrowser模块。 6.解释下Python的and-or语法 这里需要大致知道and和or用于列表和数字之间的区别。 7.如何倒序迭代一个数组 # 通用方法 for i in range(len(l)-1, -1,-1): print(l[i]) # 内置函数reversed for i in reversed(l): print(i) 8.Python是怎样进行类型变换的 9.Python里面如何实现tuple和list的转换

Python核心技术与实战——十九|一起看看Python全局解释器锁GIL

允我心安 提交于 2019-12-05 22:57:38
  我们在前面的几节课里讲了Python的并发编程的特性,也了解了多线程编程。事实上,Python的多线程有一个非常重要的话题——GIL(Global Interpreter Lock)。我们今天就来讲一讲这个GIL。 一个不解之谜 我们先来看一看这个例子: def CountDown(n): while n>0: n -= 1 现在,我们假设有个很大的数字n=100000000,我们来试试单线程的情况下 执行这个函数,然后看看怎么执行的 import time def main(): start_time = time.perf_counter() n = 100000000 CountDown(n) end_time = time.perf_counter() print('take {} seconds'.format(end_time-start_time)) if __name__ == '__main__': main() ##########运行结论########## take 8.2776216 seconds 这还是在我的第八代i7的笔记本上运行的结论,这时候我们想要用多线程的方式来加速,比如下面的操作 from threading import Thread n = 100000000 t1 = Thread(target=CountDown,args=[n/

python关于多线程的GIL问题,以及CPU分配核数的问题

感情迁移 提交于 2019-12-05 20:41:12
对于Python中,多线程的问题详细描述: 在Python中,其实对于多线程的运行方案并不完美,纯属的Python多线程运行时,只能实现并发执行,对于现在的多核CPU来说,有点浪费CPU资源,但在其他的语言中,并没有这个问题。 这一切都是由于时代的原因,在上个世纪80年代,由于硬件的发展,当时的电脑只是单核CPU,并没有今天的多核CPU。发明Python语言的龟叔,为了实现单核多任务的操作,提出了一个相当精彩的概念,就是GIL。 GIL解决了单核CPU多任务的问题,但随着硬件的发展,同样也暴露出了GIL的缺点,即不能实现在多核CPU的今天,多线程的多任务并行执行。 为了探讨GIL的实现,先简单简绍一下多任务的概念: 对于多任务,无论是多进程或者多线程,在具体的CPU执行阶段是按线程去分配CPU执行的,因为在CPU执行阶段会将进程分为线程执行 , 每一个进程可以细分为一个主线程和n个子线程,在真正执行的时候,是由线程去争抢CPU的时间片, 即CPU分配资源和调度的基本单位是线程。通过时间片轮流机制实现多任务的执行效果。具体的时间片轮流机制可以查阅CPU的制造商的相关网站,每家的厂商对于时间片轮流机制的算法不尽相同,但都实现了同一个功能,即让CPU不停的切换多个线程,并让每个线程执行一个或者多个时间片(即是该线程竞争到的时间片,如果在该线程执行时遇到I/O操作,CPU会释放该线程资源

Python多进程编程

一世执手 提交于 2019-12-05 20:40:55
阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiprocessing python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到 并发执行 的转换。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。 回到顶部 1. Process 创建进程的类 :Process([group [, target [, name [, args [, kwargs]]]]]),target表示调用对象,args表示调用对象的位置参数元组。kwargs表示调用对象的字典。name为别名。group实质上不使用。 方法 :is_alive()、join([timeout])、run()、start()、terminate()。其中,Process以start()启动某个进程。 属性 :authkey、daemon(要通过start()设置)、exitcode(进程在运行时为None、如果为–N

【转】python 线程,GIL 和 ctypes

…衆ロ難τιáo~ 提交于 2019-12-05 20:38:25
原文地址: http://zhuoqiang.me/python-thread-gil-and-ctypes.html GIL 与 Python 线程的纠葛 GIL 是什么东西?它对我们的 python 程序会产生什么样的影响?我们先来看一个问题。运行下面这段 python 程序,CPU 占用率是多少? # 请勿在工作中模仿,危险:) def dead_loop(): while True: pass dead_loop() 答案是什么呢,占用 100% CPU?那是单核!还得是没有超线程的古董 CPU。在我的双核 CPU 上,这个死循环只会吃掉我一个核的工作负荷,也就是只占用 50% CPU。那如何能让它在双核机器上占用 100% 的 CPU 呢?答案很容易想到,用两个线程就行了,线程不正是并发分享 CPU 运算资源的吗。可惜答案虽然对了,但做起来可没那么简单。下面的程序在主线程之外又起了一个死循环的线程 import threading def dead_loop(): while True: pass # 新起一个死循环线程 t = threading.Thread(target= dead_loop) t.start() # 主线程也进入死循环 dead_loop() t.join() 按道理它应该能做到占用两个核的 CPU 资源,可是实际运行情况却是没有什么改变

Parallel Python实现python程序的并行及多cpu多核利用

不打扰是莪最后的温柔 提交于 2019-12-05 20:36:37
为啥要这个模块: Python是解释型的语言,而Python解释器使用GIL(全局解 释器锁)来在内部禁止并行执行,正是这个GIL限制你在多核处理器上同一时间也只能执行一条字节码指令. 听朋友说python 3.0 里面已经改进, 默认有了多处理器编程的库了. Python2.XX暂时还不支持。 Parallel Python 这个库,正是为支持smp多路多核多cpu而设计的, 而且它不仅可以多核处理器协同工作,还可以通过网络集群运行。 官网: http://www.parallelpython.com/ pp模块的简介 PP 是一个Python模块,提供了在SMP(多CPU或多核)和集群(通过网络连接的多台计算机)上并行执行Python代码的机制。轻量级,易于安装,并 集成了其他软件。PP也是一个用纯Python代码实现的跨平台,开放源码模块。 下面是看起来很高端的功能介绍 ! * 在SMP和集群上并行执行Python代码 * 易于理解和实现的基于工作的并行机制,便于把穿行应用转换成并行的 * 自动构造最佳配置(默认时工作进程数量等同于系统处理器数量) * 动态处理器分配(允许运行时改变工作处理器数量) * 函数的工作缓存(透明的缓存机制确保后续调用降低负载) * 动态负载均衡(任务被动态的分配到各个处理器上) * 基于SHA的连接加密认证 * 跨平台移植(Windows

python的多线程不能利用多核CPU?

允我心安 提交于 2019-12-05 20:35:17
转自 https://www.cnblogs.com/shmily2018/p/9123144.html 为什么python的多线程不能利用多核CPU,但是咱们在写代码的时候,多线程的确是在并发,而且还比单线程快。 一、python的多线程不能利用多核CPU? 原因: 因为GIL,python只有一个GIL,运行python时,就要拿到这个锁才能执行,在遇到I/O 操作时会释放这把锁。 如果是纯计算的程序,没有 I/O 操作,解释器会每隔100次操作就释放这把锁,让别的线程有机会 执行(这个次数可以通sys.setcheckinterval 来调整)同一时间只会有一个获得GIL线程在跑,其他线程都处于等待状态 1、如果是CPU密集型代码(循环、计算等),由于计算工作量多和大,计算很快就会达到100,然后触发GIL的释放与在竞争,多个线程来回切换损耗资源, 所以在多线程遇到CPU密集型代码时,单线程会比较快 2、如果是I\O密集型代码(文件处理、网络爬虫),开启多线程实际上是并发(不是并行),IO操作会进行IO等待,线程A等待时,自动切换到线程B, 这样就提升了效率 二、其他原理解释 转:链接:https://www.zhihu.com/question/23474039/answer/24695447 地说就是作为可能是仅有的支持多线程的解释型语言(perl的多线程是残疾

python从入门到放弃之协程

寵の児 提交于 2019-12-05 17:44:20
协程 协程,又称微线程,纤程。英文名Coroutine。 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用。 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。 所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。 子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。 线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。 协程可以被认为是一种用户空间线程,与传统的抢占式线程相比,有2个主要的优点: 与线程不同,协程是自己主动让出CPU,并交付他期望的下一个协程运行,而不是在任何时候都有可能被系统调度打断。因此协程的使用更加清晰易懂,并且多数情况下不需要锁机制。 与线程相比,协程的切换由程序控制,发生在用户空间而非内核空间,因此切换的代价非常的小。 某种意义上,协程与线程的关系类似与线程与进程的关系,多个协程会在同一个线程的上下文之中运行。 协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程