Python多线程编程

线程是计算机程序实现并发处理的重要手段,它共享进程地址空间等资源,却可独立调度。 与进程相比,线程更加轻量级,线程间通讯也更为便捷。

线程使用方法因操作系统而异,操作系统原生多线程编程 API 也是五花八门。 Python 将线程编程 原语 进一步抽象,并提供一套简洁的通用 API ,复杂度已降到最低。

接下来,我们以一个最简单的例子,一览为快。

假设,我们需要启动 3 个线程,并发执行下面这个函数:

>>> def foo():
...     print('hello')
...

首先,我们从标准库 threading 包中导入 Thread 类:

>>> from threading import Thread

顾名思义, Thread 类用于创建线程对象。 我们通过列表推导创建 3 个线程对象:

>>> threads = [Thread(target=foo) for _ in range(3)]

注意到, foo 函数作为 target 参数传给了 Thread 类。 当 Thread 对象启动时,将自动执行 target 指定的 可调用对象 。 它可以是一个函数,也可以是一个对象的某个方法。

现在,我们看到刚创建的线程处于 initial ,即初始状态:

>>> threads
[<Thread(Thread-11, initial)>, <Thread(Thread-12, initial)>, <Thread(Thread-13, initial)>]

初始状态表示线程对象完成了创建,但仍未启动,更别说执行 foo 函数了。

接下来,我们调用线程对象 start 方法,将线程逐个启动:

>>> for thread in threads:
...     thread.start()
...
hello
hello
hello

我们刚启动线程,马上就看到了它们执行 foo 函数而输出的 hello ,共 3 个。

由于 foo 函数非常简短,线程很快就执行完毕,并自动停止:

>>> threads
[<Thread(Thread-11, stopped 123145333903360)>, <Thread(Thread-12, stopped 123145339158528)>, <Thread(Thread-13, stopped 123145333903360)>]

线程虽然已经执行完毕并停止了,但它们占用的系统资源却仍未释放。 因此,别忘了在线程停止后,调用 join 方法将其占用的系统资源进行释放:

>>> for thread in threads:
...     thread.join()
...

需要特别注意,如果线程还在运行, join 方法将一直阻塞,直到线程退出后才返回。

附录

订阅更新,获取更多学习资料,请关注我们的 微信公众号

微信搜索:小菜学编程
微信搜索:小菜学编程