Python 同步原语不同步

我有三个线程,两个用于读取串行接口,一个用于写入。两个读取线程的区别在于,一个管理一个优先的状态机,另一个收集测量数据并充当从机。伪代码看起来像这样...

class Test(object):
    def __init__(self,stuff):
        self._stuff = stuff
        self.q = multiprocessing.Queue()
        self.interface = serial.Serial(conn,baud)
        self.data_event = threading.Event()
        self.serial_lock = threading.Lock()
        self.sync_time = 1
        self.state = 'none'
        self.new_state = 'none'
        self.run()


    def data_collect(self):
  
        while True:
            self.data_event.wait()
            serial_output = self.interface.readline()
            # ...
            # data collection
            # do stuff,put stuff in queue
            # ...
        
            time.sleep(self.sync_time)

    def read_uart(self):

        while True:
            self.serial_lock.acquire()
            serial_output = self.interface.readline()
            # ...
            # a bunch of logic to manage the state machine
            # self.data_event.clear() in here somewhere
            # do stuff,put stuff in queue
            # ...
            self.state = self.new_state

            if(self.notify):
                self.data_event.set()
            self.serial_lock.release()
            time.sleep(self.sync_time)

    def measurement(self):
        t = threading.Thread(target=self.read_uart)
        t.setDaemon(True)
        t.start()
        t3 = threading.Thread(target=self.data_collect)
        t3.setDaemon(True)
        t3.start()

        self.interface.write("<initial command>".encode())

        while True:
            self.serial_lock.acquire()
            command = self.q.get() #other threads push commands to this queue
            self.interface.write(command.encode())
            self.serial_lock.release()
            time.sleep(self.sync_time)

    def run(self):
        t2 = threading.Thread(target=self.measuerment)
        t2.setDaemon(True)
        t2.start()

我最初在 raspberry pi 3 A+ 上进行设置时遇到了麻烦,因为状态机会冻结或读取来自串行接口的乱码输出 - 但是当我将 self.sync_time 从 0.1 增加到 1 时,一切都开始正常安排并且按预期工作。

我现在试图让代码在稍有不同的硬件上运行,经过 10-20 次完美的工作状态机循环(有时小于 10 或大于 20),测量线程将在read_uart 之前的一行,导致状态机中断。顺序是这样的:

...
ACQUIRE UART
RELEASE UART
ACQUIRE MEASURE
RELEASE MEASURE
START DATA COLLECT
END DATA COLLECT
ACQUIRE MEASURE
RELEASE MEASURE
...

正常情况下,它看起来像:

...
ACQUIRE UART
RELEASE UART
ACQUIRE MEASURE
RELEASE MEASURE
START DATA COLLECT
END DATA COLLECT
ACQUIRE UART
RELEASE UART
...

我尝试用普通的 Lock() 和条件变量替换 threading.Event(),但每次都得到相同的结果。我什至看top,看看python是不是对硬件有负担,内存和cpu有充足的资源。

我更习惯于 C 中的多线程/多处理,所以我不确定我做错了什么......

如何强制我的线程每次都以正确的顺序执行? Measure线程怎么可能在read_uart之前抢锁两次?我是否造成了某种竞争条件?

nxg2062632 回答:Python 同步原语不同步

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/29255.html

大家都在问