ste*_*eve 2 python multithreading serial-port polling raw-input
我正在研究一个python项目,该项目轮询COM端口上的数据并轮询用户输入.截至目前,该计划正在顺利运作,但似乎效率低下.我在一个单独的线程中运行的while循环中发生了串行端口轮询,并将数据粘贴到队列中.用户输入轮询也发生在一个while循环中,该循环在一个单独的线程中运行,该输入将输入粘贴到队列中.不幸的是,我有太多的代码和帖子,它会从问题的角度来看.
那么是否有更有效的方法来轮询串行或raw_input()而不将它们粘在无限循环中并在自己的线程中运行它们?
我一直在对这个主题进行大量研究,并不断遇到"单独的线程和队列"范例.但是,当我运行这个程序时,我在四核i7上使用了近30%的CPU资源.一定有更好的方法.
我曾在C中使用过ISR,并希望有类似于我可以使用的中断.我最近的研究发现了许多带有回调的"事件"库,但我似乎无法理解它们如何适应我的情况.我正在使用Windows 7(64位)计算机进行开发,但是当我完成时将成品移动到RPi.我不是在寻找代码,我只需要指向正确的方向.谢谢你的任何信息.
您看到CPU使用率很高,因为您的主线程正在使用非阻塞get_nowait调用在无限循环中轮询两个不同的队列,这意味着您的循环将在大多数情况下不断循环.不断运行循环使用CPU周期,就像任何紧密的无限循环一样.为了避免使用大量CPU,您希望让无限循环使用阻塞I/O,以便它们等到实际要处理的数据再继续之前.这样,您就不会经常运行循环,因此使用CPU.
那么,用户输入线程:
while True:
data = raw_input() # This blocks, and won't use CPU while doing so
queue.put({'type' : 'input' : 'data' : data})
Run Code Online (Sandbox Code Playgroud)
COM线程:
while True:
data = com.get_com_data() # This blocks, and won't use CPU while doing so
queue.put({'type' : 'COM' : 'data' : data})
Run Code Online (Sandbox Code Playgroud)
主线程:
while True:
data = queue.get() # This call will block, and won't use CPU while doing so
# process data
Run Code Online (Sandbox Code Playgroud)
阻塞get调用只会等到put另一个线程使用threading.Condition对象唤醒它.这不是重复的民意调查.来自Queue.py:
# Notify not_empty whenever an item is added to the queue; a
# thread waiting to get is notified then.
self.not_empty = _threading.Condition(self.mutex)
Run Code Online (Sandbox Code Playgroud)
...
def get(self, block=True, timeout=None):
self.not_empty.acquire()
try:
if not block:
if not self._qsize():
raise Empty
elif timeout is None:
while not self._qsize():
self.not_empty.wait() # This is where the code blocks
elif timeout < 0:
raise ValueError("'timeout' must be a non-negative number")
else:
endtime = _time() + timeout
while not self._qsize():
remaining = endtime - _time()
if remaining <= 0.0:
raise Empty
self.not_empty.wait(remaining)
item = self._get()
self.not_full.notify()
return item
finally:
self.not_empty.release()
def put(self, item, block=True, timeout=None):
self.not_full.acquire()
try:
if self.maxsize > 0:
if not block:
if self._qsize() == self.maxsize:
raise Full
elif timeout is None:
while self._qsize() == self.maxsize:
self.not_full.wait()
elif timeout < 0:
raise ValueError("'timeout' must be a non-negative number")
else:
endtime = _time() + timeout
while self._qsize() == self.maxsize:
remaining = endtime - _time()
if remaining <= 0.0:
raise Full
self.not_full.wait(remaining)
self._put(item)
self.unfinished_tasks += 1
self.not_empty.notify() # This is what wakes up `get`
finally:
self.not_full.release()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3799 次 |
| 最近记录: |