0

ここに私の問題の小さな実装があります。「押す」ボタンをクリックするとハングし、しばらくはハングしません。このハングをどのように克服できますか? これが私のコードです。

Sane をインストールするには、「sudo apt-get install python-imaging-sane」

import gtk
import gtk.glade
import threading
import os
import sane
gtk.gdk.threads_init()
class process(threading.Thread):
    def __init__(self,main_object):
        self.main_object = main_object
        threading.Thread.__init__(self)

    def run(self):
        sane_version = sane.init()
        sane_devices = sane.get_devices()
        gtk.threads_enter()
        self.main_object.pb.set_fraction(self.main_object.value)
        gtk.threads_leave()
        self.main_object.value = self.main_object.value + .1


class main():
    def __init__(self):
        #GUI
        window = gtk.Window()
        window.set_default_size(200,200)
        vbox = gtk.VBox(False,0)

        self.pb = gtk.ProgressBar()
        button = gtk.Button("Press me ")
        button.connect("clicked",self.fun_to_call)
        vbox.pack_end(self.pb)
        vbox.pack_end(button)
        button.show()
        self.pb.show()
        vbox.show()
        window.add(vbox)

        self.value = .1
        window.show()

    def fun_to_call(self,data=None):
        pro = process(self)
        pro.start()


main()
gtk.main()
4

2 に答える 2

0

件名に関する PyGTK FAQ を見ると、ステップが欠けているように見えます。(ただし、FAQ エントリ全体は興味深い読み物です)

...次のように、メインループを gtk.threads_enter()/gtk.threads_leave() でラップする必要があります。

gtk.threads_enter()
gtk.main()
gtk.threads_leave()

また、コードが例外をスローした場合でも が常に実行さfinallyれることを保証するための使用方法に関するアドバイスもあります。gtk.threads_leave()

ただし、この種の GUI スレッドの使用は必ずしも移植可能ではないことに注意してください。一部のオペレーティング システムでは、正しくロックされていても GUI 操作を実行する非メイン スレッドに問題がある場合があります。

于 2012-10-25T11:20:21.430 に答える
0

標準の python 実装 (「cpython」) の内部は、スレッドセーフではありません。

そのため、ロック (グローバル インタープリター ロック) を使用して、一度に 1 つの Python スレッドのみが実行されるようにします。このロックは、たとえば実行中のスレッドが I/O を行うときに解放されます。ただし、ロックが解除されない場合、他のスレッドは実行する機会がありません。

これが問題の原因だと思います。それは健全なバインディングの実装に依存します。

multiprocessingの代わりにモジュールを使用してみてくださいthreading。マルチプロセッシングは、長時間実行されるタスクに対してまったく異なるプロセスを開始するため、GIL に拘束されません。multiprocessingただし、 likeQueueによって提供される機能を使用しPipe、プロセス間で情報を交換する必要があります。

于 2012-10-25T11:25:43.587 に答える