Python 如何在两个不同线程(Class A, Class B)中共享串口

2 投票
2 回答
11966 浏览
提问于 2025-04-16 06:14

我有一个Python程序,它在使用一个串口(这是一个独特的资源),这个串口是通过一个叫A的类来管理的。程序里有两个不同的线程,分别是用B和C这两个类创建的,它们一直在通过已经创建的对象来使用这个串口资源。

import threading

Class A(threading.Thread):
    #Zigbee serial port handler
    def __init__(self,dev):
        #something here that initialize serial port
    def run():
        while True:
            #listening serial interface
    def pack(self):
        #something
    def checksum(self):
        #something
    def write(self):
        #something

Class B(threading.Thread):
    def __init__(self,SerialPortHandler):
        self.serialporthandler=SerialPortHandler
    def run(self)
        while True:
            #something that uses self.serialporthandler

Class C(threading.Thread):
    def __init__(self,SerialPortHandler):
        self.serialporthandler=SerialPortHandler
    def run(self)
        while True:
            #something that uses self.serialporthandler

def main():
    a=A('/dev/ttyUSB1')
    b=B(a)
    b.start()
    c=C(a)
    c.start()

if __name__=='main':
    while True:
        main()

问题是这两个线程同时想要访问这个串口资源。我可以使用多个A类的实例,并在关键部分加上Lock.acquire()和Lock.release()来控制访问。

有没有人能告诉我正确的做法是什么?

谢谢大家!

2 个回答

0

class A 添加一个 threading.Lock(),并在使用的时候先获取这个锁:

def __init__(self,dev):
    self.lock = threading.Lock()

def read(self):
    self.lock.acquire()
    data = ? #whatever you need to do here to read
    self.lock.release()
    return data

def write(self, data):
    self.lock.acquire()
    #whatever you need to do to write
    self.lock.release()
13

虽然你可以通过适当的锁来共享串口,但我不推荐这样做。我写过几个用Python进行串口通信的多线程应用,经验告诉我,下面的方法更好:

  • 让一个类在一个线程中管理实际的串口通信,可以使用一个或两个Queue对象:
    • 从串口读取的数据放入队列中
    • 要发送到串口的命令放入队列中,然后“串口线程”会发送这些命令
  • 其他线程通过放入和取出队列中的内容来实现逻辑

使用Queue对象会大大简化你的代码,并让它更稳定。

这种方法为你的设计打开了很多可能性。例如,你可以在串口线程管理器中注册事件(回调),当发生有趣的事件时,它会以同步的方式调用这些事件等等。

撰写回答