并发
- 同时出发,不一定同时执行。
- 多进程 multiprocessing
异步并发
- 执行时间片,在效果上神似并发的效果,
Threading
Threading.Thread
_thread 是threading模块的父类
Twisted(扭曲)框架,tornado框架的核心框架
并行
- 同时执行,不强调同时出发
多线程:讨论的是异步问题
协程:单线程,在单个线程内,自由的在两个不同函数,执行到一部分的时候, 切换。协程解决了IO等待问题,在python当中协程最原始是由yeild生成器实现的
gevent 协程框架。解决多IO问题
yield生成器案例:
"""
协程回顾
"""
# 生成器
def hello():
for i in (1,3,5):
key = yield i
print(key)
print("hello world")
# h = hello()
# print("+++++++++++++++++++++++++++++++++++++++++++++++")
# print(next(h))
# print("+++++++++++++++++++++++++++++++++++++++++++++++")
# print(next(h))
# print("+++++++++++++++++++++++++++++++++++++++++++++++")
# print(next(h))
# print("+++++++++++++++++++++++++++++++++++++++++++++++")
# print("+++++++++++++++++++++++++++++++++++++++++++++++")
# print(next(h))
# print("+++++++++++++++++++++++++++++++++++++++++++++++")
# print(h.send(10))
# print("+++++++++++++++++++++++++++++++++++++++++++++++")
# print(h.send(20))
# 实际工作中,协程至少需要两个函数
def getContent():
"""
获取内容的方法
"""
while True:
url = yield "I have content"
print("get content from url : %s"%url)
def getUrl(g):
url_list = ["url1","url2","url3","url4","url5"]
for i in url_list:
print("+++++++++++++++++++++++++++++++++++++++++++++++")
g.send(i)
print("+++++++++++++++++++++++++++++++++++++++++++++++")
if __name__ == "__main__":
g = getContent()
print(next(g))
getUrl(g)
安装gevent模块
pip install gevent
gevent官方案例
"""
gevent官方案例
"""
import gevent
def fun1():
for i in range(5):
print("I am fun 1 this is %s"%i)
gevent.sleep(0)
def fun2():
for i in range(5):
print("I am fun 2 this is %s"%i)
gevent.sleep(0)
# fun1()
# fun2()
# 交替执行
t1 = gevent.spawn(fun1)
t2 = gevent.spawn(fun2)
gevent.joinall([t1,t2])
协程锁案例:
import gevent
from gevent.lock import Semaphore
# 实例信号量
sem = Semaphore(1)
def fun1():
for i in range(5):
sem.acquire()
print("I am fun 1 this is %s"%i)
sem.release()
def fun2():
for i in range(5):
sem.acquire()
print("I am fun 2 this is %s"%i)
sem.release()
# fun1()
# fun2()
t1 = gevent.spawn(fun1)
t2 = gevent.spawn(fun2)
gevent.joinall([t1,t2])
flask基于gevent模块实现并发
Flask+gevent高效部署:当前优化适用于io访问频繁的项目,算法类型不适用。
如果Flask项目只是小规模的优化只需要将命令配置(app)当中的threaded改为True就可以了
manage.py
from app import create_app,db
from flask_script import Manager
from flask_migrate import Migrate # 用来同步数据库
from flask_migrate import MigrateCommand # 用来同步数据库的命令
from gevent import monkey
# 猴子补丁,将之前代码当中所有不契合协程的代码修改为契合
monkey.patch_all()
# 实例化app
app = create_app("running")
# 命令行封装app
manager = Manager(app)
# 绑定可以管理的数据库模型
migrate = Migrate(app,db)
# 加载数据库管理命令
manager.add_command("db",MigrateCommand)
@manager.command
def runserver_gevent():
from gevent import pywsgi
server = pywsgi.WSGIServer(("127.0.0.1",5000),app)
server.serve_forever()
if __name__ == "__main__":
manager.run()
以gevent方式运行项目:
python manage.py runserver_gevent