python的基础以及提高我爱编程

Python day18_协程

2018-05-26  本文已影响0人  g_s_007

协程的简单使用

定义:协程:又称为微线程,也可以说成用户级线程, 在不开辟线程的基础上可以完成多任务
特征: 如何理解协程: 只要在def里面只看到一个yield关键字表示就是协程,在单线程的基础上可以完成多任务,多个任务按照一定顺序交替执行.

import time


# 协程1
def work1():
    while True:
        print("work1....")
        time.sleep(0.2)
        yield


# 协程2
def work2():
    while True:
        print("work2....")
        time.sleep(0.2)
        yield


if __name__ == '__main__':
    # 创建协程对象
    g1 = work1()
    g2 = work2()

    while True:
        # 启动协程
        next(g1)
        next(g2)

greenlet 的使用(补充 实际中很少使用)

greenlet: 为了更好的让程序员使用协程可以使用greenlet,因为greent封装的yield

# 创建协程执行对应的任务
g1 = greenlet.greenlet(work1)
g2 = greenlet.greenlet(work2)
# 切换到第一个协程执行对应的任务
g1.switch()

gevent 的使用(实际中用这个)

gevent : gevent框架封装Greenlet,会根据耗时操作自动完成协程之间的切换执行

gevent 的实际案例 并发下载 网页图片

import urllib.request # 导入网络请求模块
import gevent
from gevent import monkey
# 打补丁,让gevnet能够识别网络请求的耗时操作,完成协程之间的自动切换执行
monkey.patch_all()

# 下载图片的任务函数
def download_img(img_url, img_name):
    try:
        # 根据图片地址加载网络资源数据
        response = urllib.request.urlopen(img_url)
        # 读取网络中的资源数据, 考虑到图片文件有可能比较大,然后循环读取数据
        # 打开文件写入对应图片数据
        with open(img_name, "wb") as img_file:
            while True:
                # 读取网络数据
                img_data = response.read(1024)
                if img_data:
                    # 把图片二进制数据写入到指定图片文件里面
                    img_file.write(img_data)
                else:
                    break
    except Exception as e:
        print("图片下载出现异常:", e)
    else:
        print("%s图片下载成功" % img_name)


if __name__ == '__main__':
    # 准备图片地址
    img_url1 = "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3722615040,3422677914&fm=27&gp=0.jpg"
    img_url2 = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1815077192,817368579&fm=27&gp=0.jpg"
    img_url3 = "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1073392760,440995056&fm=27&gp=0.jpg"

    # 创建协程对象指定对应的任务
    # 1. 函数名
    # 2. 函数对应的参数1: img_url2,
    # 3. 函数对应的参数2: 图片名
    g1 = gevent.spawn(download_img, img_url1, "1.jpg")
    g2 = gevent.spawn(download_img, img_url2, "2.jpg")
    g3 = gevent.spawn(download_img, img_url3, "3.jpg")
    # 主线程等待所有的协程执行完成以后程序再退出
    gevent.joinall([g1, g2, g3])
上一篇 下一篇

猜你喜欢

热点阅读