the*_*lse 2 python multithreading exception python-2.7
我正在开发一个简单的 python 脚本,它将串行通信命令发送到Arduino。我有一个发送命令的主线程,然后有另一个等待用户输入的子线程。
这应该很简单,但我希望这个过程非常快。例如,如果用户输入“stop”,我想立即停止主线程。
我想到的方法是从子线程抛出异常并捕获主线程中的异常,但我很快意识到这是不可能的,因为每个线程都在自己的上下文中运行,并且子线程无法向主线程。
我现在尝试使用属性更改子类并检查主线程中的属性,但我会导致if-statements主线程中出现很多混乱,而且这也不是一个好的解决方案,因为它不会立即停止执行。
class User_input_thread (threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.isPauseRequested = False
self.isStopRequested = False
def run(self):
while (True):
s = raw_input(">")
if s.startswith("pause"):
self.isPauseRequested = True
elif s.startswith("start"):
self.isPauseRequested = False
elif s.startswith("stop"):
self.isStopRequested = True
Run Code Online (Sandbox Code Playgroud)
这是基本的主线程:
def start_demo():
user_input_thread = User_input_thread()
user_input_thread.start()
while (True):
if (not user_input_thread.isPauseRequested):
# DO SOME WORK HERE
time.sleep(10)
if (not user_input_thread.isStopRequested):
# DO SOME WORK HERE
time.sleep(10)
Run Code Online (Sandbox Code Playgroud)
实现我想要的行为的简单方法是什么?
请不要链接到讨论线程之间异常的其他页面。至少解释一下我应该如何使用代码或修改我的代码以便我能够理解。
编辑(以下代码已经过测试)以下代码的问题是,如果事件花费无限时间,则无法停止子进程。运行示例并写入“开始”......然后子进程开始工作,然后如果您发送另一个事件“例如停止”,它将被忽略。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import threading
import time
class child_thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.stop_request = threading.Event()
self.start_request = threading.Event()
self.pause_request = threading.Event()
def run(self):
while 1:
if self.stop_request.isSet():
print 'stop request is set!!'
self.stop_request.clear()
while 1:
print "stop running..."
time.sleep(1)
if self.pause_request.isSet():
print 'pause request is set!!'
self.pause_request.clear()
while 1:
print "pause running..."
time.sleep(1)
if self.start_request.isSet():
print 'start request is set!!!'
self.start_request.clear()
while 1:
print "start running..."
time.sleep(1)
def show(self, event='stop'):
if event == 'stop':
self.stop_request.set()
elif event == 'start':
self.start_request.set()
elif event == 'pause':
self.pause_request.set()
elif event == 'exit':
print 'enter exit'
self.join(1)
def main_thread():
t1 = child_thread()
t1.start()
while 1:
s = raw_input(">")
t1.show(event=s)
if s == 'exit':
break
print 'Done! child thread has been killed'
main_thread()
Run Code Online (Sandbox Code Playgroud)
child thread对于 a 来说,控制其并不是最佳实践parent thread。我们通常反其道而行之。
在您的情况下,您可以将用户输入放在主线程中,并将您的工作放在子线程中。Python中线程之间的通信通常是通过Event和信号来完成的。如果你表现出兴趣,你可以谷歌一下。
这是您的案例的示例。希望能帮助到你。我简化了 if 条件,这不是这里的关键点。:)
#!/usr/bin/python
# -*- coding: utf-8 -*-
import threading
import time
class child_thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.stop_request = threading.Event()
self.start_request = threading.Event()
self.pause_request = threading.Event()
def run(self):
while 1:
if self.stop_request.isSet():
print 'stop request is set!!'
break
if self.pause_request.isSet():
print 'pause request is set!!'
break
if self.start_request.isSet():
print 'start request is set!!!'
break
print 'no stop/pause/start is set!!'
time.sleep(1)
def join(self, timeout=None, event='stop'):
if event == 'stop':
self.stop_request.set()
elif event == 'start':
self.start_request.set()
elif event == 'pause':
self.pause_request.set()
super(child_thread, self).join(timeout)
def main_thread():
t1 = child_thread()
t1.start()
while 1:
s = raw_input(">")
t1.join(event=s)
break
print 'Done! chile thread has been killed'
main_thread()
Run Code Online (Sandbox Code Playgroud)
这里有一篇关于 Python 线程间通信的非常好的文章。http://eli.thegreenplace.net/2011/12/27/python-threads-communication-and-stopping
编辑:
这是您更新后的请求的代码。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import threading
import time
class child_thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.stop_request = threading.Event()
self.start_request = threading.Event()
self.pause_request = threading.Event()
def run(self):
while 1:
if self.stop_request.isSet():
print 'stop request is set!!'
self.stop_request.clear()
continue
if self.pause_request.isSet():
print 'pause request is set!!'
self.pause_request.clear()
continue
if self.start_request.isSet():
print 'start request is set!!!'
self.start_request.clear()
continue
def show(self, event='stop'):
if event == 'stop':
self.stop_request.set()
elif event == 'start':
self.start_request.set()
elif event == 'pause':
self.pause_request.set()
elif event == 'exit':
print 'enter exit'
self.join(1)
def main_thread():
t1 = child_thread()
t1.start()
while 1:
s = raw_input("\n>enter exit to exit:")
t1.show(event=s)
if s == 'exit':
break
print 'Done! chile thread has been killed'
main_thread()
Run Code Online (Sandbox Code Playgroud)