python 备忘(协程,多进程)

0.multiprocessing 多进程的使用

from multiprocessing import Pool, cpu_count
import time

build_links = [1,2,3,4,5,6,7,8]
auth = 'auth'

def test(url, auth):
    time.sleep(9)
    print(url, auth)

if __name__ == '__main__':  # 必须要加,不然出错,以避免递归创建子流程。
    with Pool(processes=int(cpu_count() - 1) or 1) as pool:
        pool.starmap(test, [(link, auth) for link in build_links])


1.yield

import time

def work1():
    # 循环打印数字1
    while True:
        print("-----1-----")
        # yield可以暂时挂起该函数,跳转到调用该函数的下方
        yield
        # 延迟一秒以便观察
        time.sleep(1)

def work2():
    while True:
        print("-----2-----")
        yield
        time.sleep(1)

th1 = work1()
th2 = work2()

while True:
    # 唤醒被挂起的函数
    next(th1)
    next(th2)

yield 是类似于return的关键字,不同的是,return关键字是直接结束了函数的执行。而yield 可以通过调用 send(), next() 让函数继续从yield关键字下一条语句继续执行。
send()函数的用法 是可以传参的,send(param) 。即传一个参数给yield生成器。
next() 函数和send()不同的是它不传参。

2.greenlet

import time
import greenlet


def work1():
    # 循环打印字符串
    while True:
        print("----1----")
        # 启动th2
        th2.switch()
        time.sleep(1)

def work2():
    # 循环打印字符串
    while True:
        print("----2----")
        # 启动th1
        th1.switch()
        time.sleep(1)

# 创建携程
th1 = greenlet.greenlet(work1)
th2 = greenlet.greenlet(work2)
# 启动携程
th1.switch()

greenlet不是一种真正的并发机制,而是在同一线程内,在不同函数的执行代码块之间切换
当出现阻塞时,就显式切换到没有被阻塞的代码段执行,直到另一端代码再显示的切换到本段代码时,这段代码才会继续执行。

3.gevent

import gevent
import time

def work1():
    # 循环打印
    while True:
        print("----1----")
        # 破解sleep 使sleep不再阻塞
        gevent.sleep(1)

def work2():

    while True:
        print("----2----")
        gevent.sleep(1)

# 创建并开始执行携程
th1 = gevent.spawn(work1)
th2 = gevent.spawn(work2)
# 阻塞等待携程结束
gevent.joinall([th1,th2])

gevent的核心greenlet,并试用 epoll机制使线程实现自动切换,并保证始终有greenlet在运行,而不是等待io。
gevent.spawn()方法会创建并运行一个新的greenlet协程对象。
gevent.joinall()方法的参数是一个协程对象列表,等待所有的协程都执行完成后退出

posted @ 2020-10-20 20:18  该显示昵称已被使用了  阅读(94)  评论(0)    收藏  举报