python协程

python并行运行

生来就可爱ヽ(ⅴ<●) 提交于 2020-02-10 16:39:31
源于: 执行类代码 – MainOne.py – 函数main_faker    为保证多线程数据安全,python语言的设计中,有个全局解释锁 GIL(global interpretor lock) ,每个线程在开始运行时必须获得锁,遇到I/O或sleep挂起时释放锁,从而保证同一时刻只有一个线程在运行,多个线程在不同的时间片上执行,达到多任务的目的,使python具有 并发 能力,使得python可以充分使用CPU的单个核心。多线程并发在python网络爬虫中使用普遍,可以一次性开启大量下载任务,而大部分任务都在等待I/O的状态,比单线程速度快很多倍,另外,使用协程也能达到到多线程的的效果。    我们希望提高效率,充分利用多核CPU的优势,同时执行多个任务,做到多任务 并行 ,应该怎样做呢?既然绕不开GIL,解决方案有: 1. 使用多进程,开启多个python实例,使用进程池 2.用C/C++写出多线程代码,通过cython调用;或者将C/C++编译成dll文件(linux下为so文件),通过ctypes模块直接调用其中的代码;用python的C接口写拓展,或者用Boost.Python等。 3.换解释器,不用C语言版的Pyhton,而是使用jpython(java),pypy(python),ironpython(C#)等 python多线程demo import

python语法基础-并发编程-协程-长期维护

。_饼干妹妹 提交于 2020-02-10 05:55:57
############### 协程 ############## # 协程 # 小知识点, # 协程和进程和线程一样都是实现并发的手段, # 开启一个线程,创建一个线程,还是需要开销, # 协程 # 协程本质上是一个线程, # 什么是协程:能够在多个任务之间切换来节省一些IO时间, # 不需要再浪费线程之间的切换了,只需要做程序之间的切换, # 程序任务之间的切换也是需要消耗时间,但是开销远远小于进程线程之间的切换, # from greenlet import greenlet # # 这个模块可以实现协程的多个任务的切换, # # 这个greenlet就是真正的协程模块, # # def eat(): # print("eat start") # g2.switch() # print("eat end") # # # def play(): # print("play start") # g1.switch() # print("play end") # # # g1 = greenlet(eat) # 注册, # g2 = greenlet(play) # g1.switch() # 切换 # g2.switch() """ eat start play start eat end play end 这就是实现了协程之间的切换 """ # 我们在工作中会使用进程,线程

python 池 协程

前提是你 提交于 2020-02-09 16:58:53
# 有多少个任务就开多少个进程或者线程# 什么是池 # 要在程序开始的时候,还没提交任务先创建几个线程或者进程 # 放在一个池子里,这就是池# 为什么要用池? # 如果先开好进程/线程,那么有任务之后就可以直接使用这个池中的数据了 # 并且开好的线程或者进程会一直存在在池中,可以被多个任务反复利用 # 这样极大的减少了开启\关闭\调度线程/进程的时间开销 # 池中的线程/进程个数控制了操作系统需要调度的任务个数,控制池中的单位 # 有利于提高操作系统的效率,减轻操作系统的负担# 发展过程# threading模块 没有提供池# multiprocessing模块 仿照threading写的 Pool# concurrent.futures模块 线程池,进程池都能够用相似的方式开启\使用# 线程池# import time# import random# from threading import current_thread# from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor# def func(a,b):# print(current_thread().ident,'start',a,b)# time.sleep(random.randint(1,4))# print(current

Python学习week4

五迷三道 提交于 2020-02-08 22:50:14
装饰器:本质是函数,用来装饰其他的函数,为其它函数添加附加功能。 原则:不能改变被装饰函数的源代码和调用方式。 1、函数即‘变量’,定义一个函数相当于把函数体赋值给函数名,匿名函数相当于只有函数体没有函数名 def func1(): print('in the function') func2=func1 #和普通的整数赋值一样:a=2 b=a print(b) func2() 2、高阶函数 3、嵌套函数 装饰器=高阶函数+嵌套函数 高阶函数: 1、把一个函数名当作实参传递给另外一个函数;(在不修改被装饰函数源代码的情况下为其添加功能) 2、返回值中包含函数名。(不修改函数的调用方式) import time def bar(): time.sleep(2) print('in the bar') def timer(func): start_time=time.time() func() stop_time=time.time() print('the time of running is %s'%(stop_time-start_time)) timer(bar) 输出: in the bar the time of running is 2.0002079010009766 函数执行计时器 import time def bar(): time.sleep(2) print(

Python全栈(四)高级编程技巧之10.Python多任务-协程

社会主义新天地 提交于 2020-02-07 22:00:53
文章目录 一、生成器-send方法 1.同步、异步 2.堵塞、非堵塞 3.生成器的send()方法 二、使用yield完成多任务和yield from 1.使用yield完成多任务 2.yield from的使用 三、协程-使用greenlet&gevent完成多任务 1.协程概念 2.使用greenlet完成多任务 3.使用gevent完成多任务 4.gevent简单应用 5.进程、线程和协程对比 一、生成器-send方法 1.同步、异步 同步: 是指代码调用 IO操作 时,必须等待IO操作完成才返回的调用方式。 异步: 是指代码调用 IO操作 时,不必等IO操作完成就返回的调用方式。 同步异步比较如下: 2.堵塞、非堵塞 阻塞: 从调用者的角度出发,如果在调用的时候,被卡住,不能再继续向下运行,需要等待,就说是阻塞。 堵塞的例子有: 多个用户同时操作数据库和锁机制 Socket的 accept() 方法 input() 非阻塞: 从调用者的角度出发,如果在调用的时候,没有被卡住,能够继续向下运行,无需等待,就说是非阻塞。 3.生成器的send()方法 之前讲到生成器: def create_fib ( num ) : a , b = 0 , 1 current_num = 0 while current_num < num : yield a a , b = b , a + b

Python中多进程、多线程、协程区别和应用场景

﹥>﹥吖頭↗ 提交于 2020-02-07 04:42:10
面试很容易问到,千万别混淆: 多进程适合在CPU 密集型操作(cpu 操作指令比较多,如科学计算,位数多的浮点运算) 多线程适合在IO 密集型操作(读写数据操作较多的,比如爬虫) 线程是并发,进程是并行;进程之间相互独立,是系统分配资源的最小单位,同一个进程中的所有线程共享资源。 进程:一个运行的程序或代码就是一个进程,一个没有运行的代码叫程序。进程是系统进行资源分配的最小单位,进程拥有自己的内存空间,所以进程间数据不共享,开销大。 线程:调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程的存在而存在,一个进程至少有一个线程,叫主线程,多个线程共享内存(数据共享和全局变量),因此提升程序的运行效率。 协程:用户态的轻量级线程,调度有用户控制,拥有自己的寄存器上下文和栈,切换基本没有内核切换的开销,切换灵活。 来源: https://www.cnblogs.com/kaiping23/p/9618598.html

Python并发,异步编程框架AsyncIO简介

南笙酒味 提交于 2020-02-06 16:36:26
在进入并发编程的世界之前,先看一个对比的例子: 举例 串行执行 import time def count ( task_name ) : print ( task_name , time . strftime ( "%X" ) , "One" ) time . sleep ( 1 ) # 模拟一个需要堵塞一秒的任务 print ( task_name , time . strftime ( "%X" ) , "Two" ) def main ( ) : count ( 'Task-A' ) count ( 'Task-B' ) count ( 'Task-C' ) if __name__ == "__main__" : s = time . time ( ) main ( ) elapsed = time . time ( ) - s print ( f "Total Run Time {elapsed:.2f} seconds." ) 运行结果: Task-A 12:00:06 One Task-A 12:00:07 Two Task-B 12:00:07 One Task-B 12:00:08 Two Task-C 12:00:08 One Task-C 12:00:09 Two Total Run Time 3.04 seconds. 串行执行三次函数

python高级爬虫笔记(2)

坚强是说给别人听的谎言 提交于 2020-02-05 21:09:16
提高爬虫效率主要从三个方面开始复习。 并发 ip cookies 并发必然引发的一个结果就是反爬虫机制,这种时候爬虫的效率不会因为并发而提高,反而会因为网站的防御机制拖累爬虫的速度。 自然而然地就引出了2,代理爬虫。代理爬虫能够从多个ip发送请求,减小了单个ip的请求频率,自然触发反爬虫机制的概率也就小了很多。 但是新的问题又出现了,对于需要 登录 的网站,需要提交cookies来模拟登录情况,模拟登录不难,但是同一个cookies从不同的ip同时发送请求很明显不合常理,依然会触发反爬虫机制。 这是到目前为止我所遇到的影响爬虫效率的问题,就在这里做一个总结吧,如果后续遇到新的效率相关的问题,再做补充。 并发 前言 在2019年,我阅读了python cookbook,其中对这一方面有较为详细且透彻的讲述,比较适合有python基础的人学习。 多进程、多线程是python程序员的必修课之一。因为,即使脱离了爬虫,机器学习、web开发等方面,多线程、多进程依旧有着举足轻重的地位。 这是开发者的一个小分水岭,它在一定程度上决定了程序效率的高低。 python中的多进程方法 多线程、多进程、协程爬虫 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程

Python程序中的协程操作-greenlet模块

本秂侑毒 提交于 2020-02-04 12:12:08
目录 Python程序中的协程操作-greenlet模块 一、安装模块 二、greenlet实现状态切换 三、效率对比 Python程序中的协程操作-greenlet模块 一、安装模块 安装:pip3 install greenlet 二、greenlet实现状态切换 from greenlet import greenlet def eat(name): print('%s eat 1' %name) g2.switch('randy') print('%s eat 2' %name) g2.switch() def play(name): print('%s play 1' %name) g1.switch() print('%s play 2' %name) g1=greenlet(eat) g2=greenlet(play) g1.switch('randy')#可以在第一次switch时传入参数,以后都不需要 randy eat 1 randy play 1 randy eat 2 randy play 2 三、效率对比 单纯的切换(在没有io的情况下或者没有重复开辟内存空间的操作),反而会降低程序的执行速度。 #顺序执行 import time def f1(): res = 1 for i in range(100000000): res += i def f2():

Python之函数

耗尽温柔 提交于 2020-02-04 04:33:25
一函数基础 1.1 函数分类 a.内置函数:为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max() b.自定义函数:很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可。 1.2 定义函数 #语法 def 函数名(参数1,参数2,参数3,...): '''注释''' 函数体 return 返回的值 #1、无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印 #2、有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值 #3、空函数:设计代码结构 1.3 调用函数 1 语句形式:foo() 2 表达式形式:3*len('hello') 3 当中另外一个函数的参数:range(len('hello')) 函数练习: ''' 1、写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批了修改操作 ''' import os def foo(x,y,z): ''' :param x: 文件名 :param y: 修改的内容 :return: ''' with open(x,'r')as f_read,open('tmp.txt','w'