更新的答案
我为条形码阅读器添加了一些代码。我这样做是为了让条形码阅读器花费可变的时间,最多需要 5 秒来读取读数,而流量计需要恒定的 0.5 秒,因此您可以看到不同的线程以不同的速率相互独立地进行。
#!/usr/bin/env python3
from threading import Lock
import threading
import time
from random import seed
from random import random
# Dummy function to read SPI as I don't have anything attached
def readSPI():
# Take 0.5s to read
time.sleep(0.5)
readSPI.static += 1
return readSPI.static
readSPI.static=0
class FlowMeter(threading.Thread):
def __init__(self):
super(FlowMeter, self).__init__()
# Create a mutex
self.mutex = Lock()
self.currentReading = 0
def run(self):
# Continuously read flowmeter and safely update self.currentReading
while True:
value = readSPI()
self.mutex.acquire()
self.currentReading = value
self.mutex.release()
def read(self):
# Main calls this to get latest reading, we just grab it from internal variable
self.mutex.acquire()
value = self.currentReading
self.mutex.release()
return value
# Dummy function to read Barcode as I don't have anything attached
def readBarcode():
# Take variable time, 0..5 seconds, to read
time.sleep(random()*5)
result = "BC" + str(int(random()*1000))
return result
class BarcodeReader(threading.Thread):
def __init__(self):
super(BarcodeReader, self).__init__()
# Create a mutex
self.mutex = Lock()
self.currentReading = 0
def run(self):
# Continuously read barcode and safely update self.currentReading
while True:
value = readBarcode()
self.mutex.acquire()
self.currentReading = value
self.mutex.release()
def read(self):
# Main calls this to get latest reading, we just grab it from internal variable
self.mutex.acquire()
value = self.currentReading
self.mutex.release()
return value
if __name__ == '__main__':
# Generate repeatable random numbers
seed(42)
# Instantiate and start flow meter manager thread
fmThread = FlowMeter()
fmThread.daemon = True
fmThread.start()
# Instantiate and start barcode reader thread
bcThread = BarcodeReader()
bcThread.daemon = True
bcThread.start()
# Now you can do other things in main, but always get access to latest readings
for i in range(20):
fmReading = fmThread.read()
bcReading = bcThread.read()
print(f"Main: i = {i} FlowMeter reading = {fmReading}, Barcode={bcReading}")
time.sleep(1)
样本输出
Main: i = 0 FlowMeter reading = 0, Barcode=0
Main: i = 1 FlowMeter reading = 1, Barcode=0
Main: i = 2 FlowMeter reading = 3, Barcode=0
Main: i = 3 FlowMeter reading = 5, Barcode=0
Main: i = 4 FlowMeter reading = 7, Barcode=BC25
Main: i = 5 FlowMeter reading = 9, Barcode=BC223
Main: i = 6 FlowMeter reading = 11, Barcode=BC223
Main: i = 7 FlowMeter reading = 13, Barcode=BC223
Main: i = 8 FlowMeter reading = 15, Barcode=BC223
Main: i = 9 FlowMeter reading = 17, Barcode=BC676
Main: i = 10 FlowMeter reading = 19, Barcode=BC676
Main: i = 11 FlowMeter reading = 21, Barcode=BC676
Main: i = 12 FlowMeter reading = 23, Barcode=BC676
Main: i = 13 FlowMeter reading = 25, Barcode=BC86
Main: i = 14 FlowMeter reading = 27, Barcode=BC86
Main: i = 15 FlowMeter reading = 29, Barcode=BC29
Main: i = 16 FlowMeter reading = 31, Barcode=BC505
Main: i = 17 FlowMeter reading = 33, Barcode=BC198
Main: i = 18 FlowMeter reading = 35, Barcode=BC198
Main: i = 19 FlowMeter reading = 37, Barcode=BC198
原始答案
我建议您查看systemd
并systemctl
在每次系统启动时启动您的应用程序 - 示例在这里。
关于同时监控两件事,我建议你使用 Python 的threading模块。这是一个简单的示例,我创建了一个子类对象threading
,通过不断读取它并将当前值保存在主程序可以随时读取的变量中来管理您的流量计。您可以启动另一个类似的管理您的条形码阅读器并并行运行它们。我不想那样做,并把你的代码加倍混淆。
#!/usr/bin/env python3
from threading import Lock
import threading
import time
# Dummy function to read SPI as I don't have anything attached
def readSPI():
readSPI.static += 1
return readSPI.static
readSPI.static=0
class FlowMeter(threading.Thread):
def __init__(self):
super(FlowMeter, self).__init__()
# Create a mutex
self.mutex = Lock()
self.currentReading = 0
def run(self):
# Continuously read flowmeter and safely update self.currentReading
while True:
value = readSPI()
self.mutex.acquire()
self.currentReading = value
self.mutex.release()
time.sleep(0.01)
def read(self):
# Main calls this to get latest reading, we just grab it from internal variable
self.mutex.acquire()
value = self.currentReading
self.mutex.release()
return value
if __name__ == '__main__':
# Instantiate and start flow meter manager thread
fmThread = FlowMeter()
fmThread.start()
# Now you can do other things in main, but always get access to latest reading
for i in range(100000):
fmReading = fmThread.read()
print(f"Main: i = {i} FlowMeter reading = {fmReading}")
time.sleep(1)
您可以查看使用logging
来协调和统一您的调试和日志记录消息 - 请参见此处。
您可以查看events
让其他线程知道当某事达到临界级别时需要执行的操作 -此处为示例。