python协程

python与GIL

左心房为你撑大大i 提交于 2019-12-16 11:05:18
一、GIL是什么,它为什么会存在   python被人诟病最多的大概就是它的GIL全局锁了,但我今天要为它正名,这与python本身没有关系,而是与它的解释器有关系。   我们知道,python代码编写好,最终运行的是一个.py的文件,运行代码的过程,其实就是让解释器把我们编写的代码解释给机器能识别的语言的过程。可以解释python代码的解释器有很多,如: cpython(官方解释器) ipython(基于cpython的一种解释器,交互更强,其他与cpython一样) pypy(采用JIT(Just In Time)也就是即时编译编译器,对Python代码执行动态编译,目的是加快执行速度) jython(Java平台上的解释器) ironpython(与jython类似,只不过ironPython是运行在微软.Net平台上的Python解释器)   官方使用的解释器是cpython,也就是当我们从官网下载安装python的时候,就已经默认使用python解释器是cpython。而GIL就是cpython在解释python代码的时候给它加的一个锁,GIL全称是Global Interpreter Lock(全局解释器锁),所以GIL与cpython有关,与python无关,你可以换一种没有GIL的解释器。   那么GIL为什么会存在呢,官网的解释是:GIL是一个互斥锁

【python基础】十八、Python process 进程

被刻印的时光 ゝ 提交于 2019-12-15 03:00:14
进程 线程 协程 并发: 一个cpu, 轮流交替进行多线程 并行: 多个cpu, 同时执行,或 同时并发执行 进程 > 线程 > 协程 > 生成器 都可以实现多任务: 与特点有关 任务比较多 用进程 爬虫 用线程 或 协程 进程(Process),操作系统结构的基础, 曾经,面向进程设计的计算机结构中,进程就是程序的基本执行实体.(一个c) 当代,面向线程设计的计算机结构中,进程是线程的容器 * 优点 * 缺点 linux下 使用 fork 函数创建进程 os模块的fork windows 使用 multiprocessing模块 多进程 能否 访问 同一个全局变量? 能, 仅仅 复制 全局变量 到自己进程, 不共用 耗时用 线程 - 下载 计算用 进程 - 运算 import os import time from multiprocessing import Process n = 5 # def download ( t ) : global n # 只是取到全局n的初始值, 不与task_2 共用 while True : n -= 1.8 print ( ' -- SonProcess Task 1' , os . getpid ( ) , '-' , os . getppid ( ) , 'n:' , n ) time . sleep ( t ) def getfile

Python程序中的线程操作(oncurrent模块)

不羁岁月 提交于 2019-12-11 02:28:33
进程是cpu资源分配的最小单元,一个进程中可以有多个线程。 线程是cpu计算的最小单元。 对于Python来说他的进程和线程和其他语言有差异,是有GIL锁。 GIL锁 GIL锁保证一个进程中同一时刻只有一个线程被cpu调度。 GIL锁,全局解释器锁。用于限制一个进程中同一时刻只有一个线程被cpu调度。 扩展:默认GIL锁在执行100个cpu指令(过期时间)。 查看GIL切换的指令个数 import sys v1 = sys。getcheckinterval() print(v1) 一、通过threading.Thread类创建线程 1、 创建线程的方式:直接使用Thread from threading import Thread import time def sayhi(name): time.sleep(2) print('%s say hello' %name) if __name__ == '__main__': t = Thread(target=sayhi,args=( ' nick ' ,)) t.start() print('主线程') 2、 创建线程的方式:继承Thread from threading import Thread import time class Sayhi(Thread): def __init__(self,name): super().

Python协程与Go协程的区别二

久未见 提交于 2019-12-10 20:33:38
写在前面 世界是复杂的,每一种思想都是为了解决某些现实问题而简化成的模型,想解决就得先面对,面对就需要选择角度,角度决定了模型的质量, 喜欢此UP主 汤质看本质 的哲学科普,其中简洁又不失细节的介绍了人类解决问题的思路,以及由概念搭建的思维模型对人类解决问题的重要性与限制.也认识到学习的本质就是: 认识获取(了解概念) -> 知识学习(建立模型) -> 技能训练(实践) 阅读也好, 学习也好, 妨碍我们「理解」的障碍主要有两个: 高度抽象的概念 「模型」无法关联现象 也就是说 概念明确 + 关系明确, 才能构成「模型」, 对照「现象」, 形成「理解」。 在理解编程知识时可以关键归纳为两点: 理解核心概念群+使用场景思考与故事化讲述 这里特别推荐码农翻身中大话编程式的科普: 码农翻身全年文章精华 并发模型 并发思想的一些探寻 并发之痛 Thread, Goroutine, Actor 中有较好的总结: 陈力就列, 不能者止 能干活的代码片段就放在线程里, 如果干不了活(需要等待, 被阻塞等), 就摘下来。通俗的说就是不要占着茅坑不拉屎, 如果拉不出来, 需要酝酿下, 先把茅坑让出来, 因为茅坑是稀缺资源。 要做到这点一般有两种方案: 异步回调方案 典型如NodeJS, 遇到阻塞的情况, 比如网络调用, 则注册一个回调方法(其实还包括了一些上下文数据对象)给IO调度器

理解 Python 中的多线程

我的未来我决定 提交于 2019-12-10 19:10:43
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 我们将会看到一些在 Python 中使用线程的实例和如何避免线程之间的竞争。 你应当将下边的例子运行多次,以便可以注意到线程是不可预测的和线程每次运行出的不同结果。声明:从这里开始忘掉你听到过的关于 GIL 的东西,因为 GIL 不会影响到我想要展示的东西。 示例 1, 我们将要请求五个不同的url: 1、单线程 import time import urllib2 def get_responses(): urls = [ 'http://www.google.com', 'http://www.amazon.com', 'http://www.ebay.com', 'http://www.alibaba.com', 'http://www.reddit.com' ] start = time.time() for url in urls: print url resp = urllib2.urlopen(url) print resp.getcode() print "Elapsed time: %s" % (time.time()-start) get_responses() 输出是: http://www.google.com 200 http://www.amazon.com 200 http:/

Python进阶必读博文视频教程汇总

假如想象 提交于 2019-12-10 05:48:19
昨 天翻到了一本在github开源的书: Intermediate Python. 就有了此文, 梳理了一下一些之前翻到利于 python学习 的博文、视频等. 英文的 super Python’s super() considered super! rhettinger是python核心开发者. 这篇博文也是讲super最好最深入的博文了. 装饰器 Understanding Python Decorators 如果你还没有经常性的用装饰器, 你就要思考你的工作需求是不是的太简单了, 或者该考虑下这种AOP模式的开发的作用了 元类 What is a metaclass in Python? Metaclasses Demystified 元类是python高阶语法. 合理的使用可以减少大量重复性的代码. 防御性编程中的LBYL和EAFP Try/catch or validation for speed? 这其实就是事先检查和异常处理2个方式的讨论 __new__ 和 __init__ Python (and Python C API): new versus init 这也是一个常见的面试题. self Python “self” keyword 但是注意标题. 其实self不是一个关键词. 这里知识帮助你理解self的用意 协程和并发 A Curious Course on

python并发编程知识点总结

耗尽温柔 提交于 2019-12-10 03:51:58
1.到底什么是线程?什么是进程? Python自己没有这玩意,Python中调用的操作系统的线程和进程. 2.Python多线程情况下: 计算密集型操作:效率低,Python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调度,多线程无法利用多核优势,可以通过多进程方式解决,但是比较浪费资源. IO操作:效率高 3.Python多进程的情况下: 计算密集型操作:效率高(浪费资源),不得已而为之. IO操作:效率高(浪费资源) 4.为什么有这把GIL锁? Python语言的创始人在开发这门语言时,目的快速把语言开发出来,如果加上GIL锁(C语言加锁),切换时按照100条字节指令来进行线程间的切换. 5.Python中线程和进程(GIL锁) GIL锁,全局解释器锁.用于限制一个进程中同一时刻只有一个线程被cpu调度. 扩展:默认GIL锁在执行100个cpu指令(过期时间). 查看GIL切换的指令个数 import sys v1 = sys.getcheckinterval() print(v1) 6.为什么要创建线程? 由于线程是cpu工作的最小单元,创建线程可以利用多核优势实现并行操作(Java/C#). 注意:线程是为了工作. 7.为什么要创建进程? 进程和进程之间做数据隔离(Java/C#). 注意:进程是为了提供环境让线程工作. 8

python编程(gevent入门)

徘徊边缘 提交于 2019-12-09 03:48:13
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 大家都知道python脚本执行的时候不是很快,特别是python下面的多线程机制,长久以来一直被大家所诟病。所以,很多同学都在思考python下面有没有什么方法可以让python执行地更快一些。其中这些方法包括:1、将复杂的代码转由c完成;2、多进程并发执行;3、用多线程完成io操作等等。另外,这几年,大家讨论最多的大概还是gevent协程机制。 1、协程的基本原理 gevent的基本原理来自于libevent&libev。熟悉c语言的同学对这么一个lib应该不陌生。本质上libevent或者说libev都是一种事件驱动模型。这种模型对于提高cpu的运行效率,增强用户的并发访问非常有效。但是因为它本身是一种事件机制,所以写起来有点绕,不是很直观。所以,为了修正这个问题,有心人引入了用户侧上下文切换的机制。这就是说,如果代码中引入了带io阻塞的代码时,lib本身会自动完成上下文的切换,全程用户都是没有觉察的。这就是gevent的由来。 2、gevent安装 ubuntu下面可以直接用apt-get安装gevent库。 sudo apt-get install python-gevent 3、gevent入门 为了说明gevent的使用方法,我们可以看一段简单的代码, import

Python自动化运维之高级函数

∥☆過路亽.° 提交于 2019-12-07 23:34:35
本帖最后由 陈泽 于 2018-6-20 17:31 编辑 一、协程 1.1协程的概念 协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。(其实并没有说明白~) 那么这么来理解协程比较容易:   线程是系统级别的,它们是由操作系统调度;协程是程序级别的,由程序员根据需要自己调度。我们把一个线程中的一个个函数叫做子程序,那么子程序在执行过程中可以中断去执行别的子程序;别的子程序也可以中断回来继续执行之前的子程序,这就是协程。也就是说同一线程下的一段代码执行着执行着就可以中断,然后跳去执行另一段代码,当再次回来执行代码块的时候,接着从之前中断的地方开始执行。 比较专业的理解是:   协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。 1.2 协程的优缺点 协程的优点:   (1)无需线程上下文切换的开销,协程避免了无意义的调度,由此可以提高性能(但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力)   (2)无需原子操作锁定及同步的开销   (3)方便切换控制流

python gevent异步

别说谁变了你拦得住时间么 提交于 2019-12-07 01:05:33
安装 pip install gevent import gevent from gevent import monkey monkey.patch_all()#捕捉所有阻塞,不止接收gevent.sleep import time def f(s): print("hello-----%s"%s) time.sleep(3) def f2(s): time.sleep(3) print("hello------%s"%s) start=time.time() t=gevent.spawn(f,"f") t1=gevent.spawn(f2,"f2") gevent.joinall([t,t1]) end=time.time() print(end-start) hello-----f hello------f2 3.003866195678711 创建协程对象 gevent.spawn(函数,参数) 执行协程并阻塞等待执行完毕 gevent.joinall([协程对象],[timeout]) 来源: https://www.cnblogs.com/pfeiliu/p/12000309.html