python - 如何实现'发送一个请求,等待多个响应'同步?

时间:2015-08-18 01:00:51

标签: python multithreading synchronization

我正在编写一些代码,通过串口与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

1 个答案:

答案 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