在python中检查threadsafe-ness?

时间:2013-12-06 12:52:44

标签: python multithreading pyqt

这是我第一次涉足线程,所以对任何明显的错误道歉。

我有一个PyQt小部件,一个新进程 prog 在另一个线程中运行。在我的主线程中,我还将stdout重定向到只读QTextEdit。但是,我在引用递归时遇到错误,我担心我的线程会以一种导致print语句进入无限循环的方式相互干扰。如果我从GUI运行 prog 而不是从命令行运行,我只会遇到这些错误。我的stdout重定向正在使用this SO answer

中的代码

在伪代码中,这基本上就是我所拥有的:

gui.py

class widget(QWidget):
  def __init__(self):
    self.button = QPushButton("GO!", self)
    self.button.clicked.connect(self.start)

  def start(self):
    self.thread = TaskThread()
    sys.stdout = EmittingStream(textWritten = self.outputText)
    self.thread.start()

  def outputText(self):
    #as in answer provided in link (EmittingStream in separate module)

prog.py

class TaskThread(QThread):
  def run(self):
    '''
      Long complicated program; putting in simpler code here (e.g. loop printing to 10000) doesn't reproduce errors 
    '''
  • 有没有办法找出我的递归是由无限循环还是其他任何东西引起的?
  • 我的代码显然是线程不安全的吗?
  • 如何使函数保证是线程安全的? (链接到教程/书籍会很好!)

3 个答案:

答案 0 :(得分:0)

我可以看到你找到了错误的位置。但是没有代码,我所知道的并不多。

满足您的方向需求,我将指向您的Python配置文件。因为看起来你需要一些python分析工具。

http://docs.python.org/2/library/profile.html

和关于这个主题的答案

How can you profile a Python script?

答案 1 :(得分:0)

这很棘手,但我认为您的代码是线程不安全的。具体来说,查看其他stackoverflow答案(herehere),您似乎不应该从另一个线程(甚至是QThread)中访问另一个线程的Qt GUI对象。

由于您的代码中对print的任何调用现在都访问了Qt GUI对象,因此这似乎非常不安全。

我建议安全的是:

  1. 有一个QThread,你已经在其中实例化了输出框(从创建它的线程访问Qt GUI对象是线程安全的,并且不必在主线程中创建它)Qt GUI对象不可重入,只能在主线程中创建和使用,请参阅here因此,您需要一个QThread将事件发回主线程(使用Qt信号/插槽机制,正确完成后可以是线程安全的)
  2. 从Python Queue读取时,此QThread阻止。当它从队列中获取内容时,将其置于Qt文本框中将其发回主线程,主线程将更新输出框。
  3. 修改您的EmmittingStream以将内容放入Queue,而不是直接放入Qt输出框。

答案 2 :(得分:0)

在Qt应用程序中,您必须使用一个单独的线程来处理所有gui部分。您可以使用其他线程进行计算,但不能用于用户界面。

只需在工作线程中发布有关队列中更新的消息,并使用主线程获取这些消息并更新GUI。