不同类型的等待
- 等待“读”
例如,用户向Web服务器请求数据,Web服务器需要向其数据库请求数据,此时必须要等待数据库完成工作,Web应用会“阻塞”
阻塞代码:一个代码要等待外部系统完成工作,然后才会继续,则程序的执行会阻塞
- 等待“写”
例如,对于用户的访问,Web服务器希望记录这个Web请求的详细信息,虽然也是与数据库交互:向数据库写入信息,但是程序员(和用户)并不关心何时写入,而只关心数据确实能写入。这时用户没必要等待响应(重要的是这个代码最终被执行)
对于后面一种类型的等待,可以采用多线程并行来提高效率
并发的运行代码
在程序中并发地运行代码,线程并不是惟一的解决办法(不过必须承认,线程是所有技术中使用最多的一个)
Python中实现并发运行代码的模块:
- threading模块:后文将介绍
- multiprocessing:允许你创建多个 Python进程
如果你有多个CPU内核,这些进程可以将计算负载分摊到多个CPU上。 - asencio:允许你通过创建和指定并发例程来实现并发
这是 Python 3新增的特性,所以对于很多程序员来说,这是一个非常新的概念(还有待考查) - concurrent.futures:允许你并发地管理和运行一组任务
另外,还有实现并发运行代码的关键字
async和await关键字是 Python3.5中增加的,它们提供一种创建并发例程的标准方法
- async关键字可以用在已有的for,with和def关键字前面(目前最常见的是用在def前面)。
- await关键字可以用在(几乎)任何其他代码前面。
此处介绍用Thread
实现多线程
用Thread
实现多线程
要让应用的一些代码并发地运行, Python提供了多种选择。除了第三方模块提供的很多支持外,标准库也提供了一些内置特性可以提供帮助。
关于 Python标准库的各种并发选择,完整的列表和详细信息,见
https://docs.python.org/3/library/concurrency.html
最有名的一个特性就是threading
库,它为操作系统提供的多线程实现提供了一个高层接口
不使用多线程
假如execute_slowly函数需要15秒才能完成,则后一语句的nextfunc函数需要等待
...
execute_slowly(arg1,arg2,arg3)
nextfunc()
...
使用多线程
此时,调用t.start()
后,后一语句的nextfunc函数会继续执行。
而execute_slowly的执行由Python的threading
模块处理: threading模块会与Python解释器联手,保证最终会运行execute_slowly
from threading import Thread
...
t=Thread(target=execute_slowly, args=(arg1,arg2,arg3))
t.start()#启动线程,执行与"t"线程关联的函数
nextFunc()
...
注意,应当保证15秒内execute_slowly仍能一直访问到它所需要的各变量(而没有被主函数销毁等),否则会出错
`