前言
这里预设的需求是线程Thread-1-GetAttributes
通过GetAttributesThread
类获取模型的推断结果写入全局变量global_attribute
中,假设推断时间1s,线程Thread-2-ShowImage
根据最新推断结果展示推断图片3s,同时删除倒数第二张之前的推断结果。即总是用最新的结果进行展示,除非推断时间过长导致未有新的结果写入,则按保存的倒数第二张展示。若global_attribute
栈空,则等待写入。
注意对全局变量global_attribute
的操作时,要使用锁。
锁有两种状态——锁定和未锁定。每当一个线程比如Thread-2-ShowImage
要访问共享数据global_attribute
时,必须先获得锁定;如果已经有别的线程比如Thread-1-GetAttributes
获得锁定了,那么就让线程Thread-2-ShowImage
暂停,也就是同步阻塞;等到线程Thread-1-GetAttributes
访问完毕,释放锁以后,再让线程Thread-2-ShowImage
继续。
参考网址:线程同步
代码
#!/usr/bin/python3
import threading
import time
import random
global_attribute = []
class GetAttributesThread (threading.Thread):
def __init__(self, threadID, name):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
def run(self):
print ("当前线程: " + self.name)
while True:
global global_attribute
attributes = compute_attributes()
# 获取锁,用于线程同步
threadLock.acquire()
global_attribute.append(attributes)
# 释放锁,开启下一个线程
threadLock.release()
print('ShowImageThread: global', global_attribute, ' ;attribute: ',attributes)
class ShowImageThread(threading.Thread):
def __init__(self, threadId, name):
threading.Thread.__init__(self)
self.threadID = threadId
self.name = name
def run(self):
print("当前线程: " + self.name)
while True:
global global_attribute
if len(global_attribute) > 0:
# 获取锁,用于线程同步
threadLock.acquire()
newest_att = global_attribute.pop()
if len(global_attribute) > 1:
global_attribute = [global_attribute[-1]]
# 释放锁,开启下一个线程
threadLock.release()
print("当前线程: " ,self.name, " ;展示图片3s: ", newest_att)
time.sleep(3)
else:
time.sleep(0.5)
def compute_attributes():
'''
模拟模型推断得到attributes的过程
:return:
'''
a = random.random()
b = int(100*a)
time.sleep(1)
return b
threadLock = threading.Lock()
threads = []
# 创建新线程
thread1 = GetAttributesThread(1, "Thread-1-GetAttributes")
thread2 = ShowImageThread(2, "Thread-2-ShowImage")
# 开启新线程
thread1.start()
thread2.start()
# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)
# 等待所有线程完成
for t in threads:
t.join()
print ("退出主线程")