协程(纤程、轻型线程)

  对于操作系统来说,协程是不可见的,不需要操作系统的调度,协程是程序级别的操作单位。

  协程的效率高不高和操作系统本身没有关系,不需要操作系统调度,而是看协程的调度合不合理。

  协程指的是在同一条线程上能够相互切换多个任务,遇到io就切换实际上是我们利用协程提高线程工作效率的一种方式。

  生成器(yield)这种切换就是在一条线程上出现多个任务,着多个任务之间切换本质就是协程,单纯的切换还会浪费时间,但是如果在阻塞的时候切换,并未多个程序的阻塞时间共享,协程就足够大的提高了效率。

 

协程模块(greenlet) 在多个任务之间来回切换

from greenlet import greenlet

def paly():

  print('start play')

  g2.switch()      #开关

  time.sleep(1)

  print('end play')

def sleep():

  print('start sleep')

  time.sleep(1)

  print('end sleep')

  g1.switch()

g1 = greenlet(play)

g2 = greenelt(sleep)

g1.switch()

 

gevent模块(基于greenlet实现的,多个任务就交给gevent管理,遇到IO就是用greenlet进行切换)

import time 

import gevent

def play():

  print('start play')

  gevent.sleep(1)

  print('end play')

def sleep():

  print('start sleep')

  print('end sleep')

g1 = gevent.spawn(play)

g2 = gevent.spawn(sleep)

g1.join()

g2.join()   #精准的控制协程的任务,join是在等待‘子协程’结束之后立马结束阻塞

#   gevent.joinall([g1,g2])     =  g1.join()+g2.join()

from gevent import monkey:

monkey.patch_all()     #把下面所有的模块中的阻塞都打成一个包,然后gevent就可以识别这些阻塞事件了

 

 

协程爬虫

# 协程的爬虫
import time
from urllib.request import urlopen
url_lst = ['https://www.python.org/','https://www.yahoo.com/','https://github.com/']
def get_page(url):
ret = urlopen(url).read()
return ret.decode('utf-8')
start = time.time()
for url in url_lst:
get_page(url)
print(time.time()-start)

from gevent import monkey;monkey.patch_all()
import gevent
url_lst = ['https://www.python.org/','https://www.yahoo.com/','https://github.com/']

def get_page(url):
ret = urlopen(url).read()
return ret.decode('utf-8')
start = time.time()
g_l = []
for url in url_lst:
g = gevent.spawn(get_page,url)
g_l.append(g)

gevent.joinall(g_l)
print(time.time()-start)

 

posted on 2018-12-13 20:52  汩汩-咕咚  阅读(114)  评论(0编辑  收藏  举报