python协程

Gevent高并发网络库精解

不羁的心 提交于 2019-11-30 05:39:34
进程 线程 协程 异步 并发编程(不是并行)目前有四种方式:多进程、多线程、协程和异步。 多进程编程在python中有类似C的os.fork,更高层封装的有multiprocessing标准库 多线程编程python中有Thread和threading 异步编程在linux下主+要有三种实现select,poll,epoll 协程在python中通常会说到yield,关于协程的库主要有greenlet,stackless,gevent,eventlet等实现。 进程 不共享任何状态 调度由操作系统完成 有独立的内存空间(上下文切换的时候需要保存栈、cpu寄存器、虚拟内存、以及打开的相关句柄等信息,开销大) 通讯主要通过信号传递的方式来实现(实现方式有多种,信号量、管道、事件等,通讯都需要过内核,效率低) 线程 共享变量(解决了通讯麻烦的问题,但是对于变量的访问需要加锁) 调度由操作系统完成(由于共享内存,上下文切换变得高效) 一个进程可以有多个线程,每个线程会共享父进程的资源(创建线程开销占用比进程小很多,可创建的数量也会很多) 通讯除了可使用进程间通讯的方式,还可以通过共享内存的方式进行通信(通过共享内存通信比通过内核要快很多) 协程 调度完全由用户控制 一个线程(进程)可以有多个协程 每个线程(进程)循环按照指定的任务清单顺序完成不同的任务(当任务被堵塞时,执行下一个任务

使用python,scrapy写(定制)爬虫的经验,资料,杂。

青春壹個敷衍的年華 提交于 2019-11-30 04:20:05
近期找工作略不顺。技术无用。晚上写下了这点东西。 首先说下最近在找工作的x的大概相关技术加点路线。py 3年+,linux日常熟练,限于不擅web、手机app开发,一直无太好的可展示的东西。前段时间从一家小公司离职。年前投下,没啥的话,年后再看下。先投的py爬虫的,没合适的再看运维和py相关其他。 正文开始前略吐槽下,我之前工作的小公司,在我去之前,还是多线程urllib爬正则解析,网页编码解析从GBK,UTF8依次猜。他有点强让我走了。 我开始大量使用scrapy时,scrapy已是0.16版。这个版本相对比较成熟,该版本持续了近一年时间,13年夏发布0.18版。在网上搜scrapy资料,中文的相对较少,为数不多的几篇也多写于scrapy较早的版本(提醒看资料注意发布时间)。从旧资料看,早期的scrapy,还没有dns解析缓存,url去重等功能。到0.16时,scrapy已基本成型,差的几个功能(如HTTP长连接,仿浏览器缓存机制(RFCXXXX)的CACHE)陆续在0.18,0.20里面上实现了。 Scrapinghub (写scrapy的人搞得公司)上的产品也更丰富了。 scrapy的优点在于成熟完善,定制开发快。 scrapy对比其他我所知的定制爬虫解决方案。主要对比python内的几个方案。 JAVA:nutch,hetrix...etc

Python多进程和多线程是鸡肋嘛?【转】

雨燕双飞 提交于 2019-11-30 04:10:27
GIL是什么 Python的代码执行由 Python虚拟机(也叫解释器主循环,CPython版本)来控制,Python在设计之初就考虑到在解释器的主循环中,同时只有一个线程在运行。即每个CPU在任意时刻只有一个线程在解释器中运行。对 Python虚拟机访问的控制由全局解释锁GIL控制,正是这个锁来控制同一时刻只有一个线程能够运行。——在单核CPU下的多线程其实都只是并发,不是并行 。 并发与并行区别 并发:两个或多个事件在同一时间间隔发生,或者说交替做不同事件的能力,或者说不同的代码块交替执行。 并行:两个或者多个事件在同一时刻发生,或者说同时做不同事件的能力,或者说不同的代码块同时执行。 并发和并行的意义 并发和并行都可以处理“多任务”,二者的主要区别在于是否是“同时进行”多个的任务。但是涉及到任务分解(有先后依赖耦合度高的任务无法做到并行)、任务运行(可能要考虑互斥、锁、共享等)、结果合并。 Python 下的多线程 在Python多线程下,每个线程的执行方式,如下: 获取GIL 切换到这个线程去执行 运行代码,这里有两种机制: 指定数量的字节码指令(100个) 固定时间15ms线程主动让出控制 把线程设置为睡眠状态 释放GIL 再次重复以上步骤 在Python2中,在解释器解释执行任何 Python 代码时,都需要先获得这把锁才行(同一时间只会有一个获得了 GIL 的线程在跑

124 并发编程小结

不羁岁月 提交于 2019-11-30 03:37:01
目录 一、到底什么是线程?什么是进程? 二、Python多线程情况下: 三、Python多进程的情况下: 四、为什么有这把GIL锁? 五、Python中线程和进程(GIL锁) 六、为什么要创建线程? 七、为什么要创建进程? 八、进程和线程的区别? 九、线程创建的越多越好吗? 十、生产者消费者模型解决了什么问题? 十一、Lock和RLock的区别? 十二、进程和线程以及协程的区别? 十三、IO多路复用作用? 十四、socket默认是否是阻塞的?阻塞体现在哪里? 十五、什么是异步非阻塞? 十六、什么是同步阻塞? 十七、什么是协程? 十八、协程可以提高并发吗? 十九、提高并发方案: 二十、单线程提供并发 20.1 基于IO多路复用+socket非阻塞 20.2 协程+IO切换:gevent 20.3 基于事件循环的异步 20.3.1 方法一 20.3.2 方法二 20.4 基于事件循环的异步非阻塞框架 一、到底什么是线程?什么是进程? Python自己没有这玩意,Python中调用的操作系统的线程和进程。 二、Python多线程情况下: 计算密集型操作:效率低,Python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调度,多线程无法利用多核优势,可以通过多进程方式解决,但是比较浪费资源。 IO操作:效率高 三、Python多进程的情况下:

Python核心技术与实战 笔记

人盡茶涼 提交于 2019-11-30 03:26:27
基础篇 Jupyter Notebook 优点 整合所有的资源 交互性编程体验 零成本重现结果 实践站点 Jupyter 官方 Google Research 提供的 Colab 环境 安装 运行 列表与元组 列表和元组,都是 一个可以放置任意数据类型的有序集合 。 l = [1, 2, 'hello', 'world'] # 列表中同时含有 int 和 string 类型的元素 l [1, 2, 'hello', 'world'] tup = ('jason', 22) # 元组中同时含有 int 和 string 类型的元素 tup ('jason', 22) 列表是动态的,长度大小不固定,可以随意地增加、删减或者改变元素 (mutable) 元组是静态的,场地大小固定,无法增加删除或者改变 (immutable) 都支持负数索引; 都支持切片操作; 都可以随意嵌套; 两者可以通过 list() 和 tuple() 函数相互转换; 列表和元组存储方式的差异 由于列表是动态的,所以它需要存储指针,来指向对应的元素。增加/删除的时间复杂度均为 O(1)。 l = [] l.__sizeof__() // 空列表的存储空间为 40 字节 40 l.append(1) l.__sizeof__() 72 // 加入了元素 1 之后,列表为其分配了可以存储 4 个元素的空间 (72 -

python爬虫之线程池和进程池

天涯浪子 提交于 2019-11-30 03:19:40
python爬虫之线程池和进程池 一、需求   最近准备爬取某电商网站的数据,先不考虑代理、分布式,先说效率问题(当然你要是请求的太快就会被封掉,亲测,400个请求过去,服务器直接拒绝连接,心碎),步入正题。一般情况下小白的我们第一个想到的是for循环,这个可是单线程啊。那我们考虑for循环直接开他个5个线程,问题来了,如果有一个url请求还没有回来,后面的就干等,这么用多线程等于没用,到处贴创可贴。 二、性能考虑   确定要用多线程或者多进程了,那我们到底是用多线程还是多进程,有些人对多进程和多线程有一定的偏见,就因为python的GIL锁,下面我们说一下这两个东西的差别。 三、多线程:   一般情况下我们启动一个.py文件,就等于启动了一个进程,一个进程里面默认有一个线程工作,我们使用的多线程的意思就是在一个进程里面启用多个线程。但问题来了,为什么要使用多线程呢?我知道启动一个进程的时候需要创建一些内存空间,就相当于一间房子,我们要在这个房子里面干活,你可以想一个人就等于一个线程,你房子里面有10个人的空间跟有20个人的空间,正常情况下是不一样的,因为我们知道线程和线程之间默认是可以通信的(进程之间默认是不可以通信的,不过可以用技术实现,比如说管道)。可以多线程为了保证计算数据的正确性,所以出现了GIL锁,保证同一时间只能有一个线程在计算。GIL锁你可以基本理解为

Python连载38-协程、可迭代、迭代器、生产者消费者模型

末鹿安然 提交于 2019-11-30 02:21:30
一、生产者消费者模型 import multiprocessing from time import ctime def consumer(input_q): print("Into consumer:",ctime()) while True: #处理项 item = input_q.get() print("pull",item,"out of q")#此处替换为有用的工作 input_q.task_done()#发出信号通知任务完成 print("Out of consumer:",ctime()) #此句未执行,因为q.join()收集到四个task_done()信号后,主进程启动 def producer(sequence,output_q): print("Into producer:",ctime()) for item in sequence: output_q.put(item) print("put",item,"into_q") print("Out of producer:",ctime()) #建立进程 if __name__ == "__main__": q=multiprocessing.JoinableQueue() #运行消费者进程 cons_p = multiprocessing.Process(target=consumer,args=(q,)

第十五章、Python多线程之信号量和GIL

孤街浪徒 提交于 2019-11-30 02:14:38
目录 第十五章、Python多线程之信号量和GIL 1. 信号量(Semaphore) 2. GIL 说明: 第十五章、Python多线程之信号量和GIL 1. 信号量(Semaphore) 信号量用来控制线程并发数的,Semaphore管理一个内置的计数 器,每当调用acquire()时-1,调用release()时+1。计数器不能小于0,当计数器为 0时,acquire()将阻塞线程至同步锁定状态,直到其他线程调用release()。其实就是控制最多几个线程可以操作同享资源。 import threading import time semaphore = threading.Semaphore(5) def func(): if semaphore.acquire(): print (threading.currentThread().getName() + '获取共享资源') time.sleep(2) semaphore.release() for i in range(10) t1 = threading.Thread(target=func) t1.start() -------------------------------------------------- Thread-1获取共享资源 Thread-2获取共享资源 Thread-3获取共享资源 Thread

python 全栈开发之旅

*爱你&永不变心* 提交于 2019-11-29 21:43:10
目录 python 基础语法(未完成) python 数据类型(未完成) python 内置函数(未完成) python 常用标准库(未完成) python 类(未完成) python 进程、线程、协程(未完成) 网络编程基础(未完成) HTML使用(未完成) css(未完成) JavaScript(未完成) jQuery(未完成) MySQL使用(未完成) Django框架(未完成) 其他Web框架(未完成) 来源: https://www.cnblogs.com/lczmx/p/11535111.html

python之路——迭代器和生成器

牧云@^-^@ 提交于 2019-11-29 21:31:19
阅读目录   楔子   python中的for循环   可迭代协议   迭代器协议   为什么要有for循环   初识生成器   生成器函数   列表推导式和生成器表达式   本章小结   生成器相关的面试题 返回顶部 楔子 假如我现在有一个列表l=['a','b','c','d','e'],我想取列表中的内容,有几种方式? 首先,我可以通过索引取值l[0],其次我们是不是还可以用for循环来取值呀? 你有没有仔细思考过,用索引取值和for循环取值是有着微妙区别的。 如果用索引取值,你可以取到任意位置的值,前提是你要知道这个值在什么位置。 如果用for循环来取值,我们把每一个值都取到,不需要关心每一个值的位置,因为只能顺序的取值,并不能跳过任何一个直接去取其他位置的值。 但你有没有想过,我们为什么可以使用for循环来取值? for循环内部是怎么工作的呢? 迭代器 返回顶部 python中的for循环 要了解for循环是怎么回事儿,咱们还是要从代码的角度出发。 首先,我们对一个列表进行for循环。 for i in [1,2,3,4]: print(i) 上面这段代码肯定是没有问题的,但是我们换一种情况,来循环一个数字1234试试 for i in 1234 print(i) 结果: Traceback (most recent call last): File "test.py",