编辑 2016 年 9 月 15 日: 在我的原始代码中(仍在下面发布)我尝试将 .join()
与函数一起使用,这是一个愚蠢的错误因为它只能与线程对象一起使用。我在尝试着
(1)不断运行一个获取数据并保存到文件的线程
(2) 有第二个线程,或合并队列,一旦用户输入标志(即“停止”),它将停止程序。它不会中断数据收集/保存线程。
我需要多线程方面的帮助。我正在尝试运行两个线程,一个处理数据,第二个检查标志以停止程序。
我通过反复试验了解到,如果我的计算机不爆炸,我就无法中断 while 循环。此外,我放弃了我的 GUI 代码,因为它使我的代码在多线程方面过于复杂。
我想做的是运行一个从 Arduino 收集数据的线程,将其保存到文件中,然后重复此操作。第二个线程将扫描一个标志——它可以是一个 raw_input?我想不出用户还能做些什么来停止数据采集程序。
我非常感谢在这方面的任何帮助。这是我的代码(其中大部分是伪代码,如您所见):
#threading
import thread
import time
global flag
def monitorData():
print "running!"
time.sleep(5)
def stopdata(flag ):
flag = raw_input("enter stop: ")
if flag == "stop":
monitorData.join()
flag = "start"
thread.start_new_thread( monitorData,())
thread.start_new_thread( stopdata,(flag,))
当我尝试在 IDLE 中输入“stop”时,我得到的错误是这个。
启动的线程中出现未处理的异常 追溯(最近一次通话): 文件“c:\users\otangu~1\appdata\local\temp\IDLE_rtmp_h_frd5”,第 16 行,在停止数据中 AttributeError: 'function' 对象没有属性 'join'
我再次非常感谢任何帮助,到目前为止,我已经自学了 Python,这是我遇到的第一堵大墙。
最佳答案
您看到的错误是在函数上调用 join 的结果。您需要在 thread
对象上调用 join
。您没有捕获对线程的引用,因此无论如何您都无法调用 join
。你应该像这样加入
。
th1 = thread.start_new_thread( monitorData,())
# later
th1.join()
至于解决方案,您可以使用Queue
来实现线程之间的通信。队列用于向工作线程发送退出消息,如果工作线程一秒钟没有从队列中取出任何东西,它就会运行从 arduino 收集数据的代码。
from threading import Thread
from Queue import Queue, Empty
def worker(q):
while True:
try:
item = q.get(block=True, timeout=1)
q.task_done()
if item == "quit":
print("got quit msg in thread")
break
except Empty:
print("empty, do some arduino stuff")
def input_process(q):
while True:
x = raw_input("")
if x == 'q':
print("will quit")
q.put("quit")
break
q = Queue()
t = Thread(target=worker, args=(q,))
t.start()
t2 = Thread(target=input_process, args=(q,))
t2.start()
# waits for the `task_done` function to be called
q.join()
t2.join()
t.join()
它可能比您希望的要多一些代码,并且必须检测队列为空并出现异常有点难看,但这不依赖于任何全局变量,并且总是会立即退出。基于 sleep
的解决方案不会出现这种情况,它需要等待任何当前对 sleep
的调用完成,然后才能恢复执行。
正如其他人所说,您真的应该使用 threading
而不是旧的 thread
模块,而且我建议您学习 python 3 而不是 python 2。
关于python - (Python) 使用原始输入停止线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39501529/