python并发编程二:多线程(python多线程并行编程)

前面文章我们讲述了多进程,这章我们学习下多线程相关知识。

python中有两个线程相关的标准库,一个是_thread,另一个是threading。

_thread提供了一些线程操作相关的原语,实现为Python的内置模块,是用C语言实现的。

threading是在_thread上封装了一层,实现为python的一个模块,它更易于使用,以下例子我们使用它来讲述。

在python中使用多线程时,有一点我们要注意,就是python的全局解释器锁即GIL,由于它的存在使得同一个进程内的多个线程不能同时执行python代码,也就是说python的多线程并不能利用多核,任一时刻只能有一个线程运行python代码,GIL的限制只针对Python代码,如果你有用C语言实现的模块可以不受此限制。

既然有GIL的限制为什么我们还要用多线程呢?因为用它可以实现一些无阻塞的场景,比如GUI编程中,主线程负责界面的渲染工作,其它线程可以做耗时的任务,这样界面就不会卡住仍然可以响应我们的操作。

下面我们让我们实现这样一个需求:创建10个线程并为每个新线程分配一个唯一标识,然后执行新线程,每个线程打印出自己的标识。

一、定义打印标识的函数

我们可以认为这个标识线程会当参数传给我们,所以代码可以实现如下:

def print_id(tid):
    print(f"my id is {tid}")

二、创建线程

先导入threading模块,然后实例化threading.Thread这个类就会创建一个线程,创建线程时 需要传入target和args参数。target参数是一个可调用对象,线程启动时会调用target,这里我们传入print_id。args参数会在新线程调用target时传入,这里我们传入线程的标识id,如下代码:

threading.Thread(target=print_id, args=(tid,))

三、启动线程

创建线程对象后,我们只需要调用start方法就能启动线程了,比如对象是thread,这样调用就启动线程了:

thread.start()

四、整合程序

把上面的逻辑整合在一块,创建10个线程,然后启动并等待线程结束,如下是完整代码:

import threading

def print_id(tid):
    print(f"my id is {tid}")

thread_list = [threading.Thread(target=print_id, args=(tid,)) for tid in range(10)]
for thread in thread_list: thread.start()
for thread in thread_list: thread.join()

运行后输出如下:

my id is 0
my id is 1
my id is 2
my id is 3
my id is 4
my id is 5
my id is 6
my id is 7
my id is 8
my id is 9

是不是很简单,你学会了吗?当然threading模块有很多内容这里没有讲,如果全讲的话篇幅会非常大,想了解的的话还需要你自己找下资料看看。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注