潭州课堂25班:Ph201805201 并发(协程) 第十五课 (课堂笔记)

#斐波那契
def fid(n):
    res = []
    indx = 0
    a = 0
    b = 1
    while indx < n :
        res.append(b)
        a,b = b,a+b
        indx += 1
    return res

print(fid(1000))

  

 

#  生成器
def fid(n):
    indx = 0
    a = 0
    b = 1
    while indx < n :
        yield b             #  暂停并返回    跳出函数
        res.append(b)
        a,b = b,a+b
        indx += 1


f = fid(10)
print(f)
print(next(f))

  

 

#  生成器
import time

def fid(n):
    indx = 0
    a = 0
    b = 1
    while indx < n :
        data = yield b             #  暂停并返回    跳出函数
        time.sleep(data)
        a,b = b,a+b
        indx += 1


f = fid(10)
# #   使用 send 前,要 next 下
# f.__next__()
# 或者 先 send ( None )
f.send(None)
print(f.send(2))
print(f.send(2))
print(f.send(2))

  

#  协程 :非抢占式多任务子程序组件

import greenlet     #  pip install greenlet

from greenlet import greenlet

def tast_1():
    print(11111)
    gr2.switch()
    print(22222)

def tast_2():
    print(33333)
    print(44444)
    gr1.switch()

gr1 = greenlet(tast_1)
gr2 = greenlet(tast_2)
gr1.switch()            #   调用协程,


######

11111
33333
44444
22222

  

 

#  协程   传参

import greenlet     #  pip install greenlet

from greenlet import greenlet

def tast_1():
    print(11111)
    a = gr2.switch()        #  传参
    print(22222)
    print(a)

def tast_2():
    print(33333)
    print(44444)
    gr1.switch(123)          #  传参

gr1 = greenlet(tast_1)
gr2 = greenlet(tast_2)
gr1.switch()            #   调用协程,


#########
11111
33333
44444
22222
123

  

 遇到阻塞时自动切换, 

#  gevent HTTP 请求

from gevent import monkey;monkey.patch_all()       #  猴子补丁
import gevent
'''当 greenlet 遇到一个 IO 操作垢时候 ,自动切换到其他的 greenlet'''
import requests
# import time


def get_res(pn):
    print('开始',pn)
    requests.get('https://www.baidu.com')   #  这里耗时发生阻塞
    # time.sleep(3)
    print('结束',pn)


    #  gevent.spawn  启动协程
ta = [gevent.spawn(get_res,i) for i in range(5)]
# time.sleep(2)
gevent.joinall(ta)
# gevent.joinall(ta,timeout=1)

#  spawn   创建一个 gevent 的的协程对象,开始运行,
#   为什么  ta = [gevent.spawn(get_res,i) for i in range(5)]
#   不打印,?因为他运行为立马退出,不会打印,
#   joinall 等待所有 greenlet 执行完毕,

  

 如果没有使用猴子补丁

#  生产者与消费者

import gevent
import random
from queue import Queue     #   队列
q = Queue(2)

def con():                  #   消费者
    while True:
        print(q.qsize())
        iten = q.get()
        print('删除一个数据{}'.format(iten))


def pro():                   #   生产者
    while True:
        print(q.qsize())
        iten = random.randint(0,99)

        #    如果没有猴子补丁,程序将阻塞在这里,
        q.put(iten)
    
        print('添加一个数据{}'.format(iten))


p1 = gevent.spawn(pro)
c1 = gevent.spawn(con)
gevent.joinall([p1,c1])    

  ########

0
添加一个数据32
1
添加一个数据22
2

 在  gevent 有 queue 队列,也可实现相互切换

在上边代码中引入

from gevent.queue import Queue

 

 

引入猴子补丁

from gevent import monkey;monkey.patch_all()#  猴子补丁
#  生产者与消费者

import gevent
from gevent import monkey;monkey.patch_all()        #  猴子补丁
import random
from queue import Queue     #   队列
q = Queue(2)

def con():                  #   消费者
    while True:
        print(q.qsize())
        iten = q.get()
        print('删除一个数据{}'.format(iten))


def pro():                   #   生产者
    while True:
        print(q.qsize())
        iten = random.randint(0,99)
        q.put(iten)
        print('添加一个数据{}'.format(iten))


p1 = gevent.spawn(pro)
c1 = gevent.spawn(con)
gevent.joinall([p1,c1])

  

 

0
添加一个数据57
1
添加一个数据25
2
2
删除一个数据57
1
删除一个数据25
0

 

 

 

协程,猴子补丁,实现并发服务器

from gevent import monkey;monkey.patch_all()
import socket
import gevent

sever = socket.socket()
sever.bind(('',10000))
sever.listen(5)
print('服务器开启')

def func(conn):
    while True:
        data = conn.recv(1024)
        if data:
            print(data)
        else:break


while True:
    conn,addr = sever.accept()
    print(addr)
    gevent.spawn(func,conn)

  

posted @ 2018-07-24 05:03  25班Ph201805201  阅读(164)  评论(0编辑  收藏  举报