多线程的应用十分广泛,比如在写爬虫的时候为了提高爬虫的效率,就可以采取多线程的方式进行爬取,and so on~

python3多线程——threading库

使用方法

调用threading库中的Thread对象可以建立一个线程

1
2
3
import threading

threading.Thread(target = funcName, [*args, **kwargs], name = threadName)

建立线程后可以调用Thread.start()方法运行线程,并调用Thread.join()方法设置线程的结束位置。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import time
import threading

def func():
print('thread start')
t1 = time.time()
# do something
t2 = time.time()
print('thread end, runtime:',t2-t1)

th = threading.Thread(target = func)
th.start()
# do something
th.join()

示例中,我们定义了一个函数func(),用以输出一个线程运行的时间。我们没有在脚本中直接调用它,而是创建了一个线程th,并将函数本身以参数的形式传入构造的线程实例thThread(target=func),并调用了start()启动线程,join()设置线程结束位置。

关于为什么要有join()这个函数?

简单来说就是为了同步

我们可以假设这样的情形:主线程开启子线程之后,分配子线程执行一个耗时较长的任务,而使得主线程将先于子线程结束,而如果子线程占用的资源得不到释放,将会是十分危险的,此时使用join(),主线程将会等待子线程结束后再结束;

又或者有时候主线程需要线程处理一些数据的结果,此时也可以使用join()让主线程等待子线程结束后再往下运行。

调用start()方法实质上是调用了线程对象的run()方法,我们可以通过改写这个run()方法来自定义一个线程。也就是说,有两种常用的方法调用线程:

  1. 直接将函数作为参数传入Thread对象

  2. 继承Thread类,重写run()方法,再调用start()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import threading

# 方法一,函数传参
def sayHello(objName):
print('Hello',objName)

#方法二,对象封装
class MyThread(threading.Thread):
def __init__(self, objName):
super().__init__()
self.objName = objName

def run(self):
print('Hello', self.objName)

if __name__ == '__main__':
# 注意函数需要传参时,args参数类型应为元组,单个参数也要用括号和逗号组成元组
func_th = threading.Thread(target = sayHello, args=('Function',))
obj_th = Mythread('Object')

func_th.start()
obj_th.start()

func_th.join()
obj_th.join()

to be continue…