4

私は、プログラムを開いてそのstdoutから読み取る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スレッドからのサブプロセスを介したシェルコマンドの呼び出しがかなりありますが、正しく機能することを拒否し、segfaultが発生します。私が得た違いは、メインGUIスレッドから実行しようとしているという事実と、通常はサブスレッドから発行される信号を発行しようとしたときにセグフォールトが発生したことです。

segfaultingを回避するための私の解決策は、シェルの関与が必要なダイアログの部分を別の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 に答える