Python 串行通信和队列问题

Python 串行通信和队列问题,python,multithreading,serial-port,queue,multiprocessing,Python,Multithreading,Serial Port,Queue,Multiprocessing,我在创建多进程串行记录器时遇到一些问题。 该计划:有一个从串行端口读取数据的独立进程,将数据放入队列。主进程在一段时间后读取整个队列并处理数据 但我不确定这样做是否正确,因为有时数据顺序不正确。它适用于慢速通信 我必须锁东西吗?!有没有更聪明的方法 导入时间 导入序列号 从多处理导入进程,队列 def myProcess(q): 使用serial.serial(“COM2”,115200,8,“E”,1,超时=无)作为ser: 尽管如此: q、 put(“%02X”%ser.read(1)[0]

我在创建多进程串行记录器时遇到一些问题。 该计划:有一个从串行端口读取数据的独立进程,将数据放入队列。主进程在一段时间后读取整个队列并处理数据

但我不确定这样做是否正确,因为有时数据顺序不正确。它适用于慢速通信

我必须锁东西吗?!有没有更聪明的方法

导入时间
导入序列号
从多处理导入进程,队列
def myProcess(q):
使用serial.serial(“COM2”,115200,8,“E”,1,超时=无)作为ser:
尽管如此:
q、 put(“%02X”%ser.read(1)[0])
如果“名称”=“\uuuuuuuu主要”:
尝试:
q=队列()
p=Process(target=myProcess,args=(q,))
p、 daemon=True
p、 开始()
数据=[]
尽管如此:
打印(q.qsize())#!调试
而不是q.empty():#从队列中获取所有数据
data.append(q.get())
#过程数据(数据)#数据处理
时间。睡眠(1)#模拟数据处理
删除数据[:]#清除缓冲区
除键盘中断外:
打印(“清理”)!调试
p、 加入
更新: 我尝试了另一个基于线程的版本(见下面的代码),但效果/问题相同。结转工作正常,但结转和新数据之间的一个字节始终消失->当main读取队列时,脚本将丢失该字节

导入时间、串行、线程、队列
def读取端口(q):
使用serial.serial(“COM2”,19200,8,“E”,1,超时=无)作为ser:
当t.活着时():
q、 put(“%02X”%ser.read(1)[0])
def proc_数据(数据、crc):
#在这里处理数据
进位=数据[len(data)/2:]#调试:模拟结果(返回数据的后半部分)
回程进货
如果“名称”=“\uuuuuuuu主要”:
尝试:
q=队列。队列()
线程(目标=读取端口,参数=(q,))
t、 daemon=True
t、 开始()
数据=[]
尽管如此:
尝试:
尽管如此:
data.append(q.get_nowait())#从队列中获取所有数据
队列除外。空:
通过
打印(数据)#调试:显示结转+新数据
数据=过程数据(数据)#过程数据和存储结转
打印(数据)#调试:显示新结转
time.sleep(1)#调试:模拟处理时间
除键盘中断外:
打印(“清理”)
t、 加入(0)

考虑以下代码

1) 这两个过程是兄弟的;父级只是设置它们,然后等待control-C中断一切

2) 一个进程将原始字节放入共享队列

3) 数据的第一个字节的其他proc块。当它得到第一个字节时,它会抓取其余的数据,以十六进制输出,然后继续

4) 父进程只设置其他进程,然后使用
signal.pause()等待中断

请注意,对于
多处理
qsize()
(可能还有
empty()
)函数是不可靠的,因此上述代码将可靠地获取您的数据

来源
嗨,谢谢你的评论。我让它在Windows上工作,但最后我得到了同样的效果。我进一步研究了这个问题;请看我更新的问题。@Julian所以有时候输入数据出现故障?您所说的“故障”是什么意思?脚本检查传入数据的有效性(在上面的代码段中遗漏)。无效部分单独显示,我可以看到缺少一个字节。当另一个进程/线程正在读取队列时,它正在丢失(或者没有从串行线读取)。当我提高波特率时,可能会丢失更多的字节。如何保证从串行线读取每个字节?我试图在另一个进程/线程读取队列时,通过不将输入数据直接放入队列来缓冲输入数据。但它也不起作用。
import signal, time
import serial
from multiprocessing import Process, Queue

def read_port(q):
    with serial.Serial("COM2", 115200, 8, "E", 1, timeout=None) as ser:
        while True:
            q.put( ser.read(1)[0] )

def show_data(q):
    while True:
        # block for first byte of data
        data = [ q.get() ]
        # consume more data if available
        try:
            while True:
                data.append( q.get_nowait() )
        except Queue.Empty:
            pass
        print 'got:', ":".join("{:02x}".format(ord(c)) for c in data)

if __name__=='__main__':
    try:
        q = Queue()
        Process(target=read_port, args=(q,)).start()
        Process(target=show_data, args=(q,)).start()

        signal.pause()          # wait for interrupt

    except KeyboardInterrupt:
        print("clean-up") #!debug