编辑9/15/16:在我的原始代码中(仍在下面发布)我尝试将.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”时,我得到的错误就是这个。
线程中未处理的异常 Traceback(最近一次调用最后一次): 文件“c:\ users \ otangu~1 \ appdata \ local \ temp \ _IDLE_rtmp_h_frd5”,第16行,在stopdata中 AttributeError:'function'对象没有属性'join'
我再一次非常感谢任何帮助,到目前为止,我已经自学了Python,这是我遇到的第一个巨大的墙。
答案 0 :(得分:1)
你正在寻找这样的事情:
from threading import Thread
from time import sleep
# "volatile" global shared by threads
active = True
def get_data():
while active:
print "working!"
sleep(3)
def wait_on_user():
global active
raw_input("press enter to stop")
active = False
th1 = Thread(target=get_data)
th1.start()
th2 = Thread(target=wait_on_user)
th2.start()
th1.join()
th2.join()
您在代码中犯了一些明显的错误和一些不太明显的错误。首先,在线程对象上调用join,而不是函数。同样,join不会杀死一个线程,它等待线程完成。当没有更多代码要执行时,线程结束。如果你想要一个线程运行直到设置了一个标志,你通常会在你的线程中包含一个循环,每隔一秒左右检查一次标志(取决于你需要多长时间的精确度)。
此外,螺纹模块优于下杠杆螺纹模块。后者已在python3中删除。
答案 1 :(得分:1)
您看到的错误是在函数上调用join的结果。您需要在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.
答案 2 :(得分:0)
这是不可能的。线程功能必须完成。你不能从外面加入它。