一篇文章读懂 Python 多线程
副标题[/!--empirenews.page--]
Threading模块从 Python 1.5.2 版开始出现,用于增强底层的多线程模块thread。Threading 模块让操作多线程变得更简单,并且支持程序同时运行多个操作。 注意,Python 中的多线程最好用于处理有关 I/O 的操作,如从网上下载资源或者从本地读取文件或者目录。如果你要做的是 CPU 密集型操作,那么你需要使用 Python 的multiprocessing模块。这样做的原因是,Python 有一个全局解释器锁 (GIL),使得所有子线程都必须运行在同一个主线程中。正因为如此,当你通过多线程来处理多个 CPU 密集型任务时,你会发现它实际上运行的更慢。因此,我们将重点放在那些多线程最擅长的领域:I/O 操作! 线程简介 多线程能让你像运行一个独立的程序一样运行一段长代码。这有点像调用子进程(subprocess),不过区别是你调用的是一个函数或者一个类,而不是独立的程序。在我看来,举例说明更有助于解释。下面来看一个简单的例子:
这里,我们导入 threading 模块并且创建一个叫 doubler的常规函数。这个函数接受一个值,然后把这个值翻一番。它还会打印出调用这个函数的线程的名称,并在最后打印一行空行。然后在代码的最后一块,我们创建五个线程并且依次启动它们。在我们实例化一个线程时,你会注意到,我们把 doubler 函数传给target参数,同时也给 doubler 函数传递了参数。Args参数看起来有些奇怪,那是因为我们需要传递一个序列给 doubler 函数,但它只接受一个变量,所以我们把逗号放在尾部来创建只有一个参数的序列。 需要注意的是,如果你想等待一个线程结束,那么需要调用 join方法。 当你运行以上这段代码,会得到以下输出内容:
当然,通常情况下你不会希望输出打印到标准输出。如果不幸真的这么做了,那么最终的显示效果将会非常混乱。你应该使用 Python 的 logging 模块。它是线程安全的,并且表现出色。让我们用 logging模块修改上面的例子并且给我们的线程命名。代码如下:
代码中最大的改变就是加入了 get_logger函数。这段代码将创建一个被设置为调试级别的日志记录器。它将日志保存在当前目录(即脚本运行所在的目录)下,然后设置每行日志的格式。格式包括时间戳、线程名、日志记录级别以及日志信息。 在 doubler 函数中,我们把 print语句换成 logging 语句。你会注发现,在创建线程时,我们给 doubler 函数传入了 logger 对象。这样做的原因是,如果在每个线程中实例化 logging 对象,那么将会产生多个 logging 单例(singleton),并且日志中将会有很多重复的内容。 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |