1. 程式人生 > >python-生成器的應用

python-生成器的應用

1.實現多工

import time

def task_1():
    while True:
        print('-----1-------')
        time.sleep(0.1)
        yield

def task_2():
    while True:
        print('-------2---------')
        time.sleep(0.1)
        yield

def main():
    t1 = task_1()
    t2 = task_2()
    """
    類似於兩個while True一起執行
    先讓t1執行一會,當t1遇到yield的時候,再返回到9行
    然後執行t2,當它遇到yield的時候,再次切換到t1中
    這樣t1/t2/t1/t2的交替執行,最終實現了多工---->協程
    """
    while True:
        next(t1)
        next(t2)

main()

“”""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
並行(真的):有兩個任務,兩個cpu,一個任務佔一個cpu
併發(假的):有四個任務,兩個cpu,四個任務交替佔有cpu執行
“”"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

2.yield實現單執行緒併發

"""
利用了關鍵字yield一次性返回一個結果,阻塞,重新開始
send 喚醒
"""

import time

def consumer(name):
    print('%s 準備學習了~' %(name))
    while True:
        lesson = yield
        print('開始[%s]了,[%s]老師來講課了~' %(lesson,name))

def producer(name):
    c1 = consumer('A')
    c2 = consumer('B')
    c1.__next__()
    c2.__next__()
    print('同學們開始上課了~')
    for i in range(10):
        time.sleep(1)
        print('到了兩個同學')
        c1.send(i)             ##喚醒生成器,並返回i
        c2.send(i)

producer('westos')

3.greenlet(併發)

使用greenlet完成多工
為了更好的使用協程來完成多工,python中的greeblet模組
對其進行的封裝

from greenlet import greenlet
import time

def test1():
    while True:
        print('---A----')
        gr2.switch()
        time.sleep(0.5)      

def test2():
    while True:
        print('----B----')
        gr1.switch()
        time.sleep(0.5)

"""
greenlet這個類對yield進行的封裝
"""
gr1= greenlet(test1)
gr2 = greenlet(test2)

gr1.switch()

4.gevent(併發)

import gevent

def f1(n):
    for i in range(n):
        print(gevent.getcurrent(),i)
        gevent.sleep(0.5)            ##停止此任務0.5秒,cpu進行下一個任務

def f2(n):
    for i in range(n):
        print(gevent.getcurrent(),i)
        gevent.sleep(0.5)
        
def f3(n):
    for i in range(n):
        print(gevent.getcurrent(),i)
        #gevent.sleep(0.5)

g1 = gevent.spawn(f1,5)      ##執行5次
g2 = gevent.spawn(f2,5)
g3 = gevent.spawn(f3,5)

g1.join()
g2.join()
g3.join()
  • 使用程式下載圖片
import urllib.request

def main():
   req = urllib.request.urlopen('https://img3.doubanio.com/view/photo/m/public/p2528834770.jpg')
   img_content = req.read()
   with open('1.jpg','wb') as f:    ##w:寫模式 b:二進位制
       f.write(img_content)

main()

多張圖片
import urllib.request
import gevent
from gevent import monkey

def downloder(img_name,img_url):
   req = urllib.request.urlopen(img_url)
   img_content = req.read()
   with open(img_name,'wb') as f:
       f.write(img_content)

def main():
   gevent.joinall([
       gevent.spawn(downloder,'2.jpg','https://img3.doubanio.com/view/photo/m/public/p2528834770.jpg'),
       gevent.spawn(downloder,'3.jpg','https://img1.doubanio.com/view/photo/l/public/p2541840518.jpg'),
       gevent.spawn(downloder,'4.jpg','https://img3.doubanio.com/view/photo/l/public/p2540519750.jpg')
   ])
main()