2020-04-06

学习笔记之四十五

     并发中,进程或线程只要 一sleep,就会转让执行权出去已占用的cpu资源,Python中线程是伪多线程,因为解释器底层的锁GIL,只要创建线程就有 全局解释器锁;别的语言中需要锁时才申请加锁;

协程

   协程:又叫微线程,是Python特有的,为了当有一个协程阻塞停滞时,快速切换到其他协程运行,保证cpu的高效运转,任务快速完成,

协程实现方法有三种:
1、生成器完成,
2、greenlet (第三方包)完成,
3、gevent.spawn完成,

  greenlet已经实现了协程,但是这个需要人工切换,比较麻烦,Python还有一个强大而且能够自动切换任务的模块,

  gevent,其原理相当于 当一个greenlet遇到IO(指输入,输出,网络、文件操作等耗时任务)操作时,比如访问网络,就自动化切换到其他的greenlet,等到IO完成,在适当的时候再切换回来继续执行,

  由于IO操作非常耗时,经常使程序处于等待状态,有了gevent我们自动切换协程,就保证总有greenlet在运行,(cpu一种在运行状态,为浪费静止),而不是等待IOUrl 和path时一个意思,路径 ,比如文件路径等;


 访问网络的强大模块:requests,但是不如其的类似作用的模块有 urllib,其获得方法 response=urllib.read()

协程:微线程

进程-线程-协程
进程-模块multiprocessing中的Process类 创建运行

线程-模块multithread中的Thread类创建运行

协程:生成器完成

import time
def task1():
for i in range(3):
print(‘A’+str(i))
yield
time.sleep(0.2)

def task2():
for i in range(3):
print(‘A’+str(i))
yield
time.sleep(0.2)

if name==‘main’:

g1=task1()
g2=task2()
while True:
try:
next(g1)
next(g2)
except:
break

  上述代码先将生成器g1全部执行完毕,在执行g2,在两个生成器的sleep时间内没有切换执行任务,从而导致cpu的浪费,任务完成吧缓慢;由上引入了greenlet 模块,第三方包,需要下载:如下代码

def task1(): #任务A
for i in range(3):
print(‘A’+str(i))
time.sleep(0.2)

def task2(): #任务B
for i in range(3):
print(‘A’+str(i))
gb.switch()
time.sleep(0.2)

def task3(): #任务C
for i in range(3):
print(‘A’+str(i))
gb.switch()
time.sleep(0.2)

if name==;main’:
ga=greenlet(a)
ga=greenlet(b)
ga=greenlet©

ga.switch() 

#表示任务Asleep时主动切换,但是只是A任务运行耗时时刻切换,BC不能,所以在BC任务中也加切换语句

greenlet虽然能实现切换,但需要手动加代码切换,为了更方便引入了gevent方法(也是第三方包)但是gevent模块必须同时引入猴子补丁,如下

import geventfrom gevent
import monkey

monkey.patch_all() #表示遇到IO,网络下载等耗时阻塞时,自动切换且休眠时间(sleep)更换为gevent底层设定的时间

def task1():#任务A
for i in range(5):
print(‘A’+str(i))
time.sleep(0.2)

def task1():#任务B
for i in range(5):
print(‘A’+str(i))
time.sleep(0.2)

def task1(): #任务C
for i in range(5):
print(‘A’+str(i))
time.sleep(0.2)

if name==‘main’:
g1=gevent.spawn(a)
g2=gevent.spawn(b)
g3=gevent.dpawn©

g1.join() #表示任务A在主进程中插队
g2,join()
g3.join()

pritn(‘这是主进程大打印…’)

协程案例: 爬虫的简单应用
import requestsdef download(url): response=requests.get(uel) content=response.text

print(‘下载了{}的数据,长度为:{}’.format(url,len(content))

‘’'注意:网络下载最好的模块时requests,类似作用的urllib上述定义的方法可以改写为:

def download(url): response=urllib.request.urlopen() content=response,read()
print(‘下载了{}的数据,长度为:{}’.format(url,len(content))’’’

if name==‘main’:
urls=[‘http://www.163.com’,‘http://www.qq.com’,‘http://www.baidu.com’]
g1=gevent.spawn(download.urls[0])
g2=gevent.spawn(download.urls[1])
g3=gevent.spawn(download.urls[2])

  g1.join()    
  g2.join()   
   g3.join()#三个任务一起实现插队语句 :    

   gevent.joinall(g1,g2,g3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值