协程阻塞和充分利用资源

178 阅读2分钟
#!/usr/bin/env python2.7
# -*- conding: utf-8 -*-
# @Time : 2020/10/27 14:10
# @Author : ada
# @file : callback_Coroutine_demo.py.py
# @Project: python-script 

import gevent
from gevent import monkey; monkey.patch_all()
from gevent.queue import Queue
import time
import urllib2

def worker_callback_result(data):
    print ("post the data: %s") %(data)
    time.sleep(1)
    #print ("Get:%s" %data)
    #resp = urllib2.urlopen(data)
    #data1 = resp.read()
    #print data1
    #print('%d bytes received from %s') %(len(data1),data)


def worker_callback_info(data):
    print ("post the info: %s") %(data)


def worker_callback_progress(data):
    print ("get the url to progress:%s") %(data)

def worker_send_alert(data):
    print ("regex filter the data result:%s") %(data)
    time.sleep(5)
    print ("send alert")

def worker_write_log(data):
    print ("write task info:%s to file") %(data)
    time.sleep(1)

def test():
    time.sleep(10)
#def get_tasks(data):
tasks = Queue()

def consumer(name):
    # while not tasks.empty():
    while True:
        task = tasks.get()
        data = task
        print('Worker %s got task %s' % (name, task))
        worker_callback_info(data)
        worker_callback_result(data)

        #gevent.sleep(4)
        #time.sleep(1)
        #gevent.sleep(2)
        worker_callback_progress(data)
        worker_send_alert(data)
        worker_write_log(data)

        #print ("finish %s") %(data)
        print 'quiting time!'
urllist = ['https://www.python.org/','http://www.yahoo.com/','https://github.com/']
def product():
    while True:
        #print 'start product'
        for i in xrange(1, 5):
        #for i in urllist:
            tasks.put(i)
            gevent.sleep(0)
            #print i
        #print 'finished product'

def f(url):
    print('GET: %s' % url)
    resp = urllib2.urlopen(url)
    data = resp.read()
    print('%d bytes received from %s.' % (len(data), url))
'''

gevent.joinall([
    gevent.spawn(f,'https://www.python.org/'),
    gevent.spawn(f,'http://www.yahoo.com/'),
    gevent.spawn(f,'https://github.com/'),
])

'''
gevent.joinall([
    gevent.spawn(product),
    gevent.spawn(consumer, 'work1'),
    gevent.spawn(consumer, 'work2'),
    gevent.spawn(consumer, 'work3'),
])






这里要先说明一下,如果少了这句from gevent import monkey; monkey.patch_all() 你的协程代码可能不能正常工作。 以上是模拟业务回调需要写的一个协程版的回调,回调逻辑有n个函数。其中有一两个函数是sleep(5)的

线程和协程,除了协程是用户态消耗更少之外,线程是操作系统层级的。

在调度和启用方面,线程是你预设启多少就启多少。阻塞也在当个线程里的,而协程是你预计启动多少个协程,当协程x阻塞便切换到其它协程工作,所以本质上当你的任务阻塞时长超过,所有可工作的协程时间,协程也无法充分利用运算资源。

比如上面某些函数sleep(5),但是三个协程都已经全在工作,并且阻塞在sleep(5),这时所有的协程全是阻塞,就不能充分利用cpu资源。