我在创建多进程串行记录器时遇到了一些问题。 计划:从串口读取单独的进程,将数据放入队列。主进程在一段时间后读取整个队列并处理数据。
但我不确定这是否是正确的方法,因为有时数据的顺序不正确。它适用于缓慢的沟通。
我必须锁定什么东西吗?!有更聪明的方法吗?
import time
import serial
from multiprocessing import Process, Queue
def myProcess(q):
with serial.Serial("COM2", 115200, 8, "E", 1, timeout=None) as ser:
while True:
q.put("%02X" % ser.read(1)[0])
if __name__=='__main__':
try:
q = Queue()
p = Process(target=myProcess, args=(q,))
p.daemon = True
p.start()
data = []
while True:
print(q.qsize()) #!debug
while not q.empty(): #get all data from queue
data.append(q.get())
#proc_data(data) #data processing
time.sleep(1) #emulate data processing
del data[:] #clear buffer
except KeyboardInterrupt:
print("clean-up") #!debug
p.join()
更新: 我尝试了另一个基于线程的版本(参见下面的代码),但效果/问题相同。结转工作正常,但在'之间有一个字节。结转和新数据总是消失 - >当main读取队列时,脚本将丢失该字节?!
import time, serial, threading, queue
def read_port(q):
with serial.Serial("COM2", 19200, 8, "E", 1, timeout=None) as ser:
while t.is_alive():
q.put("%02X" % ser.read(1)[0])
def proc_data(data, crc):
#processing data here
carry = data[len(data)/2:] #DEBUG: emulate result (return last half of data)
return carry
if __name__=='__main__':
try:
q = queue.Queue()
t = threading.Thread(target=read_port, args=(q,))
t.daemon = True
t.start()
data = []
while True:
try:
while True:
data.append(q.get_nowait()) #get all data from queue
except queue.Empty:
pass
print(data) #DEBUG: show carry-over + new data
data = proc_data(data) #process data and store carry-over
print(data) #DEBUG: show new carry-over
time.sleep(1) #DEBUG: emulate processing time
except KeyboardInterrupt:
print("clean-up")
t.join(0)
答案 0 :(得分:0)
请考虑以下代码。
1)这两个过程是兄弟姐妹;父母只是设置它们然后等待control-C中断一切
2)一个proc将原始字节放在共享队列上
3)第一个数据字节的其他proc块。当它获得第一个字节时,它会抓取剩余的数据,以十六进制输出,然后继续。
4)父proc只是设置其他人然后使用signal.pause()
请注意,对于multiprocessing
,qsize()
(可能empty()
)函数不可靠 - 因此上述代码可以可靠地获取您的数据。
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