0

基本的に、DeviceAdded DBusイベント(誰かがUSBドライブを接続したときなど)をリッスンするPythonプログラムがあり、イベントが発生したときに、新しく接続されたデバイスでメタデータを収集するスレッドを作成したいと思います。ただし、これを非同期で実行したいと思います。つまり、これらのイベントをリッスンし続けることができる親に制御を戻しながら、1つのスレッドがデバイスでメタデータを収集し続けることを許可します。現時点では、コレクションが終了するまでスレッドがブロックされます。これが私のコードのサンプルです:

class DeviceAddedListener:
def __init__(self):
    self.bus = dbus.SystemBus()
    self.hal_manager_obj = self.bus.get_object("org.freedesktop.Hal", "/org$
    self.hal_manager = dbus.Interface(self.hal_manager_obj, "org.freedeskto$
    self.hal_manager.connect_to_signal("DeviceAdded", self._filter)

def _filter(self, udi):
    device_obj = self.bus.get_object ("org.freedesktop.Hal", udi)
    device = dbus.Interface(device_obj, "org.freedesktop.Hal.Device")

    if device.QueryCapability("volume"):
        return self.capture(device)

def capture(self,volume):
    self.device_file = volume.GetProperty("block.device")
    self.label = volume.GetProperty("volume.label")
    self.fstype = volume.GetProperty("volume.fstype")
    self.mounted = volume.GetProperty("volume.is_mounted")
    self.mount_point = volume.GetProperty("volume.mount_point")
    try:
        self.size = volume.GetProperty("volume.size")
    except:
        self.size = 0

    print "New storage device detected:"
    print " device_file: %s" % self.device_file
    print " label: %s" % self.label
    print " fstype: %s" % self.fstype
    if self.mounted:
        print "  mount_point: %s" % self.mount_point
    response = raw_input("\nWould you like to acquire %s [y/N]? " % self.device_file)
    if (response == "y"):
        self.get_meta()
        thread.start_new_thread(DoSomething(self.device_file))
    else:
        print "Returning to idle"


if __name__ == '__main__':
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
DeviceAddedListener()
loop.run()

どんな考えでも大歓迎です:)スペースを節約するためにインポートリストを除外しました

4

1 に答える 1

2

_filter()関数の次の行を次のように変更して、キャプチャ用のスレッドを生成してみてください。

if device.QueryCapability("volume"):
    threading.start_new_thread(self.capture, (device))

これは、作業の大部分がcapture()関数で行われていることを前提としています。そうでない場合は、おそらく関数全体で、少し早くスレッドを生成します_filter()。これにより、フィルタリングされたデバイスが検出されるたびに新しいスレッドが生成されます。私はdbusを行ったことがなく、これを実際にテストすることはできませんが、それはアイデアです。

また、キャプチャ関数からユーザー入力を取得しようとしていますが、これは、定義したアプリを使用して、スレッドで行うのは実際には良いことではありません。最初のプロンプトがまだ画面に表示されているときに2番目のデバイスが接続された場合はどうなりますか?うまく再生できない可能性があります。

このもののデザインは、特定の理由であなたが望む通りになっているかもしれませんが、私はそれがかなり滑らかになる可能性があると感じずにはいられません。私の知る限り、スレッドを念頭に置いて設計されているわけではありません。

于 2009-08-13T00:53:12.160 に答える