Python - 多线程threading开发使用详解1(创建多线程、守护线程、阻塞线程、定时器)
作者:hangge | 2022-11-21 08:55
高级语言通常都内置多线程的支持,Python 也不例外,并且 Python 的线程是真正的 Posix Thread,而不是模拟出来的线程。在 Python3 中,通过 threading 模块提供线程的功能。下面通过样例进行介绍。
(2)另一种是在实例化 threading.Thread 对象的时候,将线程要执行的任务函数作为参数传入线程。
(2)如果线程 daemon 属性为 True,则把子线程设置为守护线程,即主线程结束运行后,无论子线程运行与否,都会和主线程一起结束。
(3)当然使用线程对象的 setDaemon(True) 方法也可以达到同样的效果:
(2)如果一个线程中调用另一个线程的 join 方法,调用者被阻塞,直到被调用线程被终止。比如下面样例,主调线程将一直堵塞到被调线程结束。
(3)join() 方法有一个参数是 timeout,表示超时时间:
一、创建多线程
(1)Python 支持两种创建多线程的方式,一种是继承 Thread 类,并重写它的 run() 方法:
注意:如果没有指定线程的名字,则默认是 Thread-X,其中 X 是序号,由 1 开始,第一个创建的线程名字就是 Tread-1。
import threading # 自定义一个线程类,继承threading.Thread类 class MyThread(threading.Thread): def __init__(self, thread_name, arg1, arg2): # 注意:一定要显式的调用父类的初始化函数。 super(MyThread, self).__init__(name=thread_name) self.arg1 = arg1 self.arg2 = arg2 def run(self): print("%s运行中......" % self.name, self.arg1, self.arg2) # 创建2个线程对象 t1 = MyThread('线程1','a','b') t2 = MyThread('线程2','101','102') # 启动线程 t1.start() t2.start() print("主线程结束")
(2)另一种是在实例化 threading.Thread 对象的时候,将线程要执行的任务函数作为参数传入线程。
注意:如果没有指定线程的名字,则默认是 Thread-X,其中 X 是序号,由 1 开始,第一个创建的线程名字就是 Tread-1。
import threading # 自定义一个方法,供线程调用 def myMethod(arg1, arg2): print("%s运行中......" % threading.currentThread().getName(), arg1, arg2) # 创建2个线程对象 t1 = threading.Thread(name="线程1", target=myMethod, args=('a','b')) t2 = threading.Thread(name="线程2", target=myMethod, args=('101','102')) # 启动线程 t1.start() t2.start() print("主线程结束")
二、守护线程
(1)默认情况下,主线程结束时,如果子线程没有运行结束,是不会和主线程一起结束的。
import threading import time # 自定义一个方法,供线程调用 def myMethod(): for i in range(5): time.sleep(1) print('子线程运行中...',i) # 创建1个线程对象 t1 = threading.Thread(target=myMethod) t1.start() print("主线程结束")
(2)如果线程 daemon 属性为 True,则把子线程设置为守护线程,即主线程结束运行后,无论子线程运行与否,都会和主线程一起结束。
import threading import time # 自定义一个方法,供线程调用 def myMethod(): for i in range(5): time.sleep(1) print('子线程运行中...',i) # 创建1个线程对象 t1 = threading.Thread(target=myMethod, daemon=True) t1.start() print("主线程结束")
(3)当然使用线程对象的 setDaemon(True) 方法也可以达到同样的效果:
注意:setDaemon() 方法必须在 start() 之前调用,否则会引发 RuntimeError 异常。
import threading import time # 自定义一个方法,供线程调用 def myMethod(): for i in range(5): time.sleep(1) print('子线程运行中...',i) # 创建1个线程对象 t1 = threading.Thread(target=myMethod) t1.setDaemon(True) t1.start() print("主线程结束")
三、阻塞线程
(1)多线程执行过程中,每个线程各执行各的任务,不等待其它的线程,自顾自的完成自己的任务。比如下面样例,虽然子线程还没结束,主线程并不会等待子线程结束后才结束。
import threading import time # 自定义一个方法,供线程调用 def myMethod(): for i in range(5): time.sleep(1) print('子线程运行中...',i) # 创建1个线程对象 t1 = threading.Thread(target=myMethod) t1.start() print("主线程结束")
(2)如果一个线程中调用另一个线程的 join 方法,调用者被阻塞,直到被调用线程被终止。比如下面样例,主调线程将一直堵塞到被调线程结束。
import threading import time # 自定义一个方法,供线程调用 def myMethod(): for i in range(5): time.sleep(1) print('子线程运行中...',i) # 创建1个线程对象 t1 = threading.Thread(target=myMethod) t1.start() t1.join() print("主线程结束")
(3)join() 方法有一个参数是 timeout,表示超时时间:
- 如果子线程 daemon 属性为 False:主线程会在等待 timeout 时间后结束,但子线程也不会被强制结束。
- 如果子线程 daemon 属性为 True:主线程会在等待 timeout 时间后结束,同时子线程也会被强制结束。
import threading import time # 自定义一个方法,供线程调用 def myMethod(): for i in range(5): time.sleep(1) print('子线程运行中...',i) # 创建1个线程对象 t1 = threading.Thread(target=myMethod) t1.start() t1.join(3) print("主线程结束")
四、定时器 Timer
定时器 Timer 类是 threading 模块中的一个小工具,用于指定 n 秒后执行某操作。
from threading import Timer def hello(): print("Welcome to hangge.com") # 表示2秒后执行hello函数 t = Timer(2, hello) t.start()
全部评论(0)