4

我试图在 python 中运行一个程序,该程序打开一个程序并从它的标准输出中读取。当我运行程序代码时,我遇到了分段错误错误,但是当我将代码放入函数 Myfunc 的线程之外时,它可以完美地工作!我不明白发生了什么:这是我的代码:

class Workspace(QMainWindow, Ui_MainWindow):
    """ This class is for managing the whole GUI `Workspace'.
        Currently a Workspace is similar to a MainWindow
    """

    def __init__(self):
        #p= subprocess.Popen(["java -Xmx256m -jar bin/HelloWorld.jar"],cwd=r'/home/karen/sphinx4-1.0beta5-src/sphinx4-1.0beta5/', shell=True, stdout=subprocess.PIPE, bufsize= 4024)
        try:
            from Queue import Queue, Empty
        except ImportError:
            while True:
    #from queue import Queue, Empty  # python 3.x
                print "error"

        ON_POSIX = 'posix' in sys.builtin_module_names

        def enqueue_output(out, queue):
            for line in iter(out.readline, b''):
                queue.put(line)
            out.close()

        p= Popen(["java -Xmx256m -jar bin/HelloWorld.jar"],cwd=r'/home/karen/sphinx4-1.0beta5-src/sphinx4-1.0beta5/',stdout=PIPE, shell=True, bufsize= 4024)
        q = Queue()
        t = threading.Thread(target=enqueue_output, args=(p.stdout, q))
        #t = Thread(target=enqueue_output, args=(p.stdout, q))
        t.daemon = True # thread dies with the program
        t.start()

# ... do other things here
        def myfunc(q):
            while True:

                try: line = q.get_nowait()
         # or q.get(timeout=.1)
                except Empty:
                    print('Vacio')
                else: # got line
    # ... do something with line

                    print line  


        thread = threading.Thread(target=myfunc, args=(q,))
        thread.start()

错误:

Segmentation fault (core dumped)
4

1 回答 1

5

我最近遇到了同样的问题。我通过子进程从运行良好的依赖 GUI 线程调用了很多 shell 命令,但一个只是拒绝正常工作并出现段错误。我遇到的不同之处在于,我正试图从主 GUI 线程运行它,而当我试图发出通常从子线程发出的信号时,它出现了段错误!

我避免段错误的解决方案是将需要一些 shell 参与的对话框部分移动到单独的QThread,有效地继承了我的应用程序中其他线程正在使用的相同公共类。问题消失了!QThread是关键!

代码架构:

class Dialog(QtGui.QDialog):

     def __init__(self):
         ...
         QtCore.QObject.connect(self.ui.listwidget_a, QtCore.SIGNAL("itemClicked(QListWidgetItem)", self.do_work)
         ...

     def do_work(self, qlistwidgetitem):
         ...
         wc = WorkerClass(str(qlistwidgetitem.text()))
         wc.start()
         wc.wait()
         my_result = wc.getResult()


 class WorkerClass(CommonClass):
     string = ""
     result = ""
     def __init__(string)
         super(WorkerClass, self).__init__()
         self.string = string

     def run():
         self.execute_shell(self.string)
         self.result = self.shell_output

     def get_result(self):
         return self.result

  class CommonClass(QtCore.QThread):

     self.shell_output = ""

     def execute_shell(string):
         ...
         p = Popen(...)
         self.shell_output, self.shell_error = p.communicate()
         self.output_ready.emit(self.shell_output) 
# that last line is where i was segfaulting 
# before I made WorkerClass (my dialog class was 
# inherinting CommonClass directly but it wasn't 
# working in separate thread) 

我希望这会有所帮助!

于 2012-12-20T19:06:34.633 回答