我目前遇到线程加入问题。我有一个函数,根据给定的参数执行一组操作。有一个“启动”按钮,它将启动该功能,该功能作为一个线程运行。
相同的按钮变成“停止”按钮,单击时将停止该功能。不幸的是,线程似乎没有结束。
相关代码在这里......注意“self.stop_com_loop”用于结束线程......
任何评论都会很棒。
def Start_Com(self):
"""
Start Com Funtion
"""
self.AppendText("\n-----------------Start Communication to Modbus-----------------\n")
self.stop_com_loop = False
cmd = ("modpoll.exe -p 504 -1 192.168.1.100")
self.AppendText("Executing Command: %s" %(cmd))
while(not self.stop_com_loop):
self._runcommand(cmd)
time.sleep(1)
self.logging_cb.Enable(True)
self.ping_btn.Enable(True)
self.com_btn.SetLabel(START_COM_STR)
self.AppendText("\n-----------------End Communication to Modbus-----------------\n")
print("Why Won't I die?")
def _com_evt(self,
evt):
"""
Com Button Event
"""
if self.com_btn.GetLabelText() == START_COM_STR:
self.logging_cb.Enable(False)
self.ping_btn.Enable(False)
self.com_btn.SetLabel(STOP_COM_STR)
self.com_thread = threading.Thread(target=self.Start_Com)
self.com_thread.daemon = True
self.com_thread.start()
elif self.com_btn.GetLabelText() == STOP_COM_STR:
self.stop_com_loop = True
# self.com_thread.join() # When this line is inserted. System Hangs
while(True):
print self.com_thread
print self.com_thread.isAlive()
if not self.com_thread.isAlive():
break
time.sleep(1)
self.com_btn.SetLabel(START_COM_STR)
else:
self.AppendText("Unknown Start Com Button State")
def _runcommand(self,
cmd):
"""
Run Command given and output to text control
"""
self.error_occured = False
cmd_l = cmd.split(" ")
self.pjob = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
stdin=subprocess.PIPE,
bufsize=0,
creationflags = subprocess.CREATE_NEW_PROCESS_GROUP)
while True:
line = self.pjob.stdout.readline()
skip_line = False
for token in self.DO_NOT_PRINT_TOKEN_L:
if ((token in line)):
skip_line = True
if skip_line:
continue
wx.Yield()
if line.strip() == "":
pass
elif self.ERROR_COM_TOKEN in line:
self.error_occured = True
self.AppendText("%-30s~ ERROR: %s\n" %(self.GetTime(),
line.strip()))
else:
self.AppendText("%-30s~ %s" %(self.GetTime(),
line.strip()))
if not line: break
# Print that error occured and when error resolves
if self.error_occured:
self.AppendText("\nXXXXXXXXXXXXXXXXXXXXX %% ERROR OCCURED %% XXXXXXXXXXXXXXXXXXXXX\n")
self.last_one_was_error = True
self.AppendOverviewText("%-30s~ %% ERROR OCCURED %% "
%(self.GetTime()))
else:
if self.last_one_was_error:
self.AppendText("\n+++++++++++++++++++++ ** ERROR RESOLVED ** +++++++++++++++++++++\n")
self.AppendOverviewText("%-30s~ ** ERROR RESOLVED ** "
%(self.GetTime()))
self.last_one_was_error = False
self.pjob.wait()
self.pjob = None
编辑: 我已经孤立到似乎阻止线程加入的行... AppendText函数似乎阻止线程加入。我不知道为什么。
logging_ctrl的初始化
self.logging_ctrl = wx.TextCtrl(self, -1, "",
style=wx.TE_MULTILINE | wx.TE_READONLY)
AppendText方法:
def AppendText(self,
text):
"""
Append text to logging text control and file is logging is enabled
"""
self.logging_ctrl.AppendText(str(text) + '\n')
答案 0 :(得分:0)
您不得在线程中使用大多数wx
次调用。必须仅从主线程调用wx
图形例程。
要解决这个问题,有一个安全的wx.CallAfter()
方法允许从线程注册操作。
在AppendText
方法中,只需:
def AppendText(self,
text):
"""
Append text to logging text control and file is logging is enabled
"""
wx.CallAfter(self.logging_ctrl.AppendText,str(text) + '\n')
如果你在主线程中,那将会像以前一样。在其他线程中,它将避免您获得的锁定,因为它只记下要执行的操作,并且wx mainloop处理它。您可能无法以图形方式看到差异,但您的线程将正确退出。