主要参考文章:https://www.cnblogs.com/ArsenalfanInECNU/p/10134591.html
threading是python中用于线程相关操作的模块。python当前版本的多线程库没有实现优先级、线程组,线程也不能被停止、暂停、恢复、中断。本文章主要介绍threading模块的主要类与函数。
1.threading模块概览
threading模块提供的类:
Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。
threading 模块提供的常用方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
threading 模块提供的常量:
threading.TIMEOUT_MAX 设置threading全局超时时间。
2.threading模块常用类
2.1 Thread类
Thread是线程类,有两种使用方法:方法一,直接在target传入要运行的方法;方法二,或从Thread继承并覆盖run()。推荐使用方法一,将目标函数作为target参数传入,非常简单。下面是两种使用方法:
方法一:
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
def sub_thread(arg):
print("thread arg is :%s\n" % str(arg))
def run_thread():
th_list = []
for i in xrange(5):
t = threading.Thread(target=sub_thread,args=(i,))
th_list.append(t)
t.start()
for t in th_list:
t.join()
if __name__ == '__main__':
run_thread()
输出:
thread arg is :0
thread arg is :1
thread arg is :2
thread arg is :3
thread arg is :4
方法二:
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
class MyThread(threading.Thread):
def __init__(self, arg):
super(MyThread, self).__init__()
self.arg = arg
def run(self):
print("thread arg is: %s\n" % str(self.arg))
def run_thread():
th_list = []
for i in xrange(5):
t = MyThread(i)
th_list.append(t)
t.start()
for t in th_list:
t.join()
if __name__ == '__main__':
run_thread()
输出和方法一相同
Thread类的相关方法:
构造方法:
Thread(group=None, target=None, name=None, args=(), kwargs={})
group: 线程组,目前还没有实现,库引用中提示必须是None;
target: 要执行的方法;
name: 线程名;
args/kwargs: 要传入方法的参数。
实例方法:
isAlive(): 返回线程是否在运行。正在运行指启动后、终止前。
get/setName(name): 获取/设置线程名。
start(): 线程准备就绪,等待CPU调度
is/setDaemon(bool): 将该子线程设置为父线程的守护线程(默认为非守护线程(False))。(需要在线程start之前设置)
start(): 启动线程。
join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。
下面解释常用的实例方法:
2.1.1 关键参数setDaemon
该参数规定当前线程是否属于守护线程,需要在线程start之前设置,默认为非守护线程(False)。
- True: 设置该子进程为父进程的守护进程,即后台线程。主线程执行过程中,子线程也在进行,主线程执行完毕后,子线程不论成功与否,主线程和子线程均停止。
- False:设置该子进程为父进程的非守护进程,即前台进程。主线程执行过程中,子线程也在进行,主线程代码执行完毕后,仍需要等待子线程也执行完成后,主线程才会停止。
当线程设置为非守护线程时,主线程要等待所有子线程执行完之后,才停止程序。举例如下:
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time
def daemon_test(arg):
time.sleep(1)
print("daemon thread args is: %s\n" % arg)
def run_daemon():
th_list = []
for i in xrange(5):
t = threading.Thread(target=daemon_test, args=(i,))
t.setDaemon(False)
th_list.append(t)
t.start()
if __name__ == '__main__':
run_daemon()
print("main process over")
输出为:
main process over
daemon thread args is: 4
daemon thread args is: 1
daemon thread args is: 0
daemon thread args is: 3
daemon thread args is: 2
设置非线程守护时,主线程执行过程中,子线程也在进行,主线程执行完毕后,等待子线程也执行完成后,主线程停止。
当线程设置守护线程时:
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time
def daemon_test(arg):
time.sleep(1)
print("daemon thread args is: %s\n" % arg)
def run_daemon():
th_list = []
for i in xrange(5):
t = threading.Thread(target=daemon_test, args=(i,))
t.setDaemon(True)
th_list.append(t)
t.start()
if __name__ == '__main__':
run_daemon()
print("main process over")
输出:
main process over
设置线程守护时,主线程执行完毕后,无论子线程执行与否,主线程和子线程均停止。
2.1.2 关键参数join
作用为阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。即当子进程的join()函数被调用时,主线程就被阻塞住了,意思为不再继续往下执行。
值得注意的是,由于join()会阻塞其他函数,如果我们要用for循环触发多个线程的执行,start()要和join()分开,即一次用两个for循环,先用第一个for循环将全部子线程start(),再用第二个for循环将全部子线程join,不然会让多线程并行执行,变成多线程依次执行:
- 因为如果其他线程还没有start(),那么由于start()操作属于主线程的调用,那么start()会被阻塞,我们原本想要的多线程并行执行会变成多线程依次执行。
- 如果此时其他线程已经start()了,那么join()函数由于是对子线程的操作,不属于主线程,则不会被阻塞。
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time
def join_test(arg):
time.sleep(1)
print("daemon thread args is: %s\n" % arg)
def run_join():
th_list = []
for i in xrange(5):
t = threading.Thread(target=daemon_test, args=(i,))
t.setDaemon(False)
th_list.append(t)
t.start()
for t in th_list:
t.join()
if __name__ == '__main__':
run_join()
print("main process over")
输出:
daemon thread args is: 1
daemon thread args is: 0
daemon thread args is: 3
daemon thread args is: 4
daemon thread args is: 2
main process over
2.2 Timer类
Timer(定时器)是Thread的派生类,用于在指定时间后调用一个方法。
构造方法:
Timer(interval, function, args=[], kwargs={})
interval: 指定的时间
function: 要执行的方法
args/kwargs: 方法的参数
实例方法:
Timer从Thread派生,没有增加实例方法。
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
def timer_test():
print("timer thread start")
if __name__ == '__main__':
t = threading.Timer(3, timer_test)
t.start()
该例子为3秒之后调用函数