Python常用模块之threading和Thread模块及线程通信
简介
Python中可以使用Thread模块和threading模块来创建线程。其中Thread模块是低级模块,用于低级别的线程控制,而threading模块是高级模块,对Thread模块进行了封装,使得线程更加方便使用。本文将对这两个模块进行详细讲解,并讨论线程之间是如何进行通信的。
基本使用方法
使用Thread模块创建线程
使用Thread模块创建线程,需要完成以下步骤:
- 导入Thread模块
- 定义一个函数,作为线程要执行的任务
- 创建Thread对象,将定义的函数作为参数传递给它
- 调用Thread对象的start方法,启动线程
下面是一个示例代码:
import thread
import time
# 线程函数
def my_thread(name, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print(name, "执行了", count, "次")
# 创建两个线程,并启动它们
try:
thread.start_new_thread(my_thread, ("线程1", 1))
thread.start_new_thread(my_thread, ("线程2", 2))
except:
print("线程创建失败")
while True:
pass # 无限循环,保持主线程不关闭
以上代码创建了两个线程,并启动它们。这两个线程会分别每秒钟和每两秒钟执行一次,分别输出"线程1"和"线程2"。
使用threading模块创建线程
使用threading模块创建线程,需要完成以下步骤:
- 导入threading模块
- 定义一个类,继承自threading.Thread,重写run方法作为线程要执行的任务
- 创建线程对象,将自定义的线程类实例作为参数传递给它
- 调用线程对象的start方法,启动线程
下面是一个使用threading模块创建线程的示例代码:
import threading
import time
# 线程类
class MyThread(threading.Thread):
def __init__(self, name, delay):
super().__init__()
self.name = name
self.delay = delay
def run(self):
count = 0
while count < 5:
time.sleep(self.delay)
count += 1
print(self.name, "执行了", count, "次")
# 创建两个线程,并启动它们
try:
t1 = MyThread("线程1", 1)
t2 = MyThread("线程2", 2)
t1.start()
t2.start()
except:
print("线程创建失败")
while True:
pass # 无限循环,保持主线程不关闭
这个代码与使用Thread模块创建线程的代码是等效的。
线程通信
Python中的线程之间可以使用多种方式进行通信,常见的方式包括:
- 使用共享变量
- 使用队列
- 使用事件
使用共享变量
共享变量是多个线程可以访问并修改的变量。对于共享变量,需要使用线程锁来保证数据的正确性。
下面是一个使用共享变量进行线程通信的示例代码:
import threading
import time
# 共享变量
g_num = 0
g_num_lock = threading.Lock()
# 线程类
class MyThread(threading.Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
global g_num
while True:
g_num_lock.acquire() # 获得线程锁
if g_num >= 10:
g_num_lock.release() # 如果已经大于等于10,就释放线程锁
break
g_num += 1
print(self.name, "把 g_num 变成了", g_num)
g_num_lock.release() # 释放线程锁
# 创建两个线程,并启动它们
try:
t1 = MyThread("线程1")
t2 = MyThread("线程2")
t1.start()
t2.start()
except:
print("线程创建失败")
while True:
if g_num >= 10:
break
time.sleep(1)
print("所有线程执行结束")
以上代码使用了一个共享变量g_num,两个线程不断对它进行加1操作,并输出结果。如果g_num已经大于等于10,则线程执行结束。
使用队列
队列是一个线程安全的数据结构,可以用来在线程之间传递数据。队列提供了put和get方法,分别用于将数据加入队列和从队列中取出数据。当队列为空或已满时,put和get方法会阻塞。
下面是一个使用队列进行线程通信的示例代码:
import threading
import time
from queue import Queue
# 队列
q = Queue()
# 线程类
class ProducerThread(threading.Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
while True:
if q.qsize() < 10:
q.put(1)
print(self.name, "向队列中加入了一个数据,当前队列大小为", q.qsize())
time.sleep(1)
else:
print("队列已满,等待1秒")
time.sleep(1)
class ConsumerThread(threading.Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
while True:
if q.qsize() > 0:
q.get()
print(self.name, "从队列中取出了一个数据,当前队列大小为", q.qsize())
time.sleep(1)
else:
print("队列已空,等待1秒")
time.sleep(1)
# 创建两个线程,并启动它们
try:
t1 = ProducerThread("生产者线程")
t2 = ConsumerThread("消费者线程")
t1.start()
t2.start()
except:
print("线程创建失败")
while True:
pass # 无限循环,保持主线程不关闭
以上代码包含了一个生产者线程和一个消费者线程,生产者线程将数据加入队列,消费者线程从队列中取出数据。当队列已满或已空时,线程会等待1秒再进行操作。
使用事件
事件是一种线程同步机制,用于在线程之间传递信号。事件有set和clear方法,分别用于设置和清除事件标志,wait方法用于阻塞线程,直到事件标志被设置。
下面是一个使用事件进行线程通信的示例代码:
import threading
import time
# 事件
e = threading.Event()
# 线程类
class WaitThread(threading.Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print(self.name, "等待事件触发")
e.wait() # 等待事件
print(self.name, "收到了事件")
# 创建线程并启动它
try:
t = WaitThread("等待线程")
t.start()
except:
print("线程创建失败")
time.sleep(2) # 等待2秒
# 触发事件
e.set()
print("事件被触发")
while True:
pass # 无限循环,保持主线程不关闭
以上代码包含了一个等待线程和一个触发事件的主线程。等待线程调用wait方法等待事件触发,而主线程使用set方法触发事件,并输出相关信息。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python常用模块之threading和Thread模块及线程通信 - Python技术站