返回 导航

Python / AI

hangge.com

Python - 多线程threading开发使用详解1(创建多线程、守护线程、阻塞线程、定时器)

作者:hangge | 2022-11-21 08:55
    高级语言通常都内置多线程的支持,Python 也不例外,并且 Python 的线程是真正的 Posix Thread,而不是模拟出来的线程。在 Python3 中,通过 threading 模块提供线程的功能。下面通过样例进行介绍。

一、创建多线程

(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)

回到顶部