我正在编写一些代码,通过串口与MCU通信。 MCU侧基本上是请求/响应服务器。 我的应用程序发送一个请求,MCU发回一个或多个响应。 但是,响应可以异步到达并具有随机延迟,但响应顺序将保持不变。 此外,我的应用程序可以一次发送多个请求。
我为每个请求创建一个线程。 并且只有一个公共线程用于从串口接收。
目前的结构是这样的:
请求线程写入串行端口,将其标识添加到等待列表,然后等待事件。 接收线程接收响应,在等待列表中查找,如果匹配请求线程正在等待,则删除等待列表条目,并设置事件。 请求线程获得有关事件的通知并继续处理。 如果每个请求只收到一个响应,则效果很好。
现在说预计会有两个回复。 处理完第一个响应后,请求线程再次将自己添加到等待列表中,并等待另一个事件。
通常,接收线程在接收第二个响应时执行相同的操作来设置事件。
但是,有时候,在请求线程等待第二个事件之前,第二个响应只是太快了。
示例代码如下。
请求线程:
send_a_request(req)
add_waitlist(req, self)
self.event = threading.Event()
if not self.event.wait(1):
remove_waitlist(req, self)
#time out processing
else:
# process 1st response
add_waitlist(req, self)
self.event = threading.Event()
if not self.event.wait(1):
remove_waitlist(req, self)
# timeout processing
else:
# process 2nd response
接收线程:
receive_a_reponse()
for (req, thread) in waitlist:
if a match is found:
remove_waitlist(req, thread)
thread.event.set()
break
答案 0 :(得分:0)
您应该在添加到队列之前和删除之前锁定。
# lock object common to all threads
lock = threading.Lock()
with lock:
send_a_request(req)
add_waitlist(req, self)
self.event = threading.Event()
if not self.event.wait(1):
with lock:
remove_waitlist(req, self)
#time out processing
else:
# process 1st response
with lock:
add_waitlist(req, self)
self.event = threading.Event()
if not self.event.wait(1):
with lock:
remove_waitlist(req, self)
# timeout processing
else:
# process 2nd response
receive_a_reponse()
with lock:
for (req, thread) in waitlist:
if a match is found:
remove_waitlist(req, thread)
thread.event.set()
break