【问题标题】:Python: Setting event from multiple threadsPython:从多个线程设置事件
【发布时间】:2017-08-30 18:44:03
【问题描述】:

我有 2 个线程正在侦听 2 条不同的 UART 线路上的数据,这些线路可以随时进入。我还有一个第三个线程,它只是一个计时器。在我的主线程中,我想等待这三个线程中的任何一个发出信号,以触发解析数据和更新类型函数。

是否使用 1 个事件和一个单独的标志,每个线程在设置事件之前都会设置该标志以指示其中一个触发事件是可接受的解决方案,还是有更好的方法来做到这一点,我错过了?

使用python 2.7

例如:

'''
UART RX thread for GNSS
'''
def uart_rx_gnss( threadName, ser):
  global event_flag
  global rx_buffer

  while(1):
    line = ser.readline()
    logger.debug(" GNSS >> " + str(line))

    with t_lock:
      rx_buffer = line
      event_flag = EVENT_GNSS
      t_event.set()      

'''
UART RX thread for cc1350
'''
def uart_rx_cc1350( threadName, ser, t_lock, t_event):
  global event_flag
  global rx_buffer

  while(1):
    cc1350_buffer = ser.readline()
    logger.debug(" CC1350 >> " + str(cc1350_buffer))

    with t_lock:
      rx_buffer = line
      event_flag = EVENT_CC1350
      t_event.set()


'''
  Periodically update if no uart
'''
def periodic_update( threadName, t_lock, t_event ):
  global event_flag

  while(1):
    time.sleep(3)
    with t_lock:
      event_flag = EVENT_TIMEOUT
      t_event.set()

'''
Main
'''
def main(verbosity="info", mode="normal"):
  # SIGING Handler 
  signal.signal(signal.SIGINT, signal_handler)

  ######### GLOBAL VARIABLES #########  
  global event_flag

  ser = ic.initialize_uart('/dev/ttymxc6', 9600)
  thread.start_new_thread( uart_rx_gnss, ("Thread-GNSS-RX", ser ) )

  ser = ic.initialize_uart('/dev/ttymxc4')
  thread.start_new_thread( uart_rx_cc1350, ("Thread-cc1350-RX", ser, lock, event ) )

  thread.start_new_thread( periodic_update, ("Updater", lock, event ) )

  # Main Loop
  while (running == True):
    event.wait()

    if (event_flag == EVENT_TIMEOUT):
      logger.info("EVENT: TIMEOUT")
      # UPDATE
    elif (event_flag == EVENT_GNSS):
      logger.info("EVENT: GNSS")
      # Parse rx_buffer
    elif (event_flag == EVENT_CC1350):
      logger.info("EVENT: CC1350") 
      # Parse rx_buffer
    else:
      logger.info("EVENT UNKNOWN")   

    event_flag = 0
    event.clear()

【问题讨论】:

    标签: python multithreading events


    【解决方案1】:

    这会爆炸。

    您只需要两个关闭事件,您的全局evetn_flag 将在竞争条件下被覆盖。

    你应该为此使用队列。

    https://docs.python.org/3/library/queue.html

    队列将保留顺序,并保证您的主线程将处理所有到达的事件。

    您可以将任意数据结构发布到队列 - 因此,由于您已经有一个事件类型“准枚举”,您可以发布一个以这个 event_type 作为第一个元素的元组,以及您必须通信的任何数据线程作为第二个元素。只需在生成线程之前创建一个queue.Queue 对象,您甚至可以将其设置为全局变量,并使用队列的get 方法而不是event.wait()

    【讨论】:

    • 谢谢,这听起来像是一个更好的解决方案。话虽如此,锁不会阻止您描述的竞争条件吗?
    • 如何为三个线程中的每一个使用一个单独的变量而不是一个 event_flag?例如:timeout_flag、gnss_flag、cc1350_flag。在我看来,这将避免竞争条件。也就是说,听起来队列是一个更好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2020-10-04
    • 1970-01-01
    • 2015-03-05
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    相关资源
    最近更新 更多