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()方法的参数是一个协程对象列表,等待所有的协程都执行完成后退出