【问题标题】:Python threading question - returning control to parentPython线程问题 - 将控制权返回给父级
【发布时间】:2009-08-13 00:37:30
【问题描述】:

基本上,我有一个 python 程序来侦听 DeviceAdded DBus 事件(例如,当有人插入 USB 驱动器时),当事件发生时,我想创建一个线程来收集新连接的设备上的元数据。但是,我想异步执行此操作 - 也就是说,允许一个线程继续收集设备上的元数据,同时将控制权返回给可以继续侦听这些事件的父级。目前,我的线程阻塞,直到收集完成。这是我的代码示例:

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()

任何想法将不胜感激 :) 我已排除导入列表以节省空间

【问题讨论】:

  • 抽象一点后,浏览示例代码会容易得多。

标签: python multithreading dbus


【解决方案1】:

通过将 _filter() 函数中的以下行更改为以下行,尝试为捕获内容生成一个线程:

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

这是假设大部分工作发生在capture() 函数中。如果没有,那么就早一点产生线程,可能在整个_filter() 函数上。 然后,这应该为检测到的每个过滤设备生成一个新线程。请记住,我没有做过任何 dbus 的东西,也无法真正对此进行测试,但这是一个想法。

此外,您正在尝试从捕获函数中获取用户输入,使用您定义的应用程序,这在线程中并不是一件好事。如果在第一个提示仍在屏幕上时连接了第二个设备怎么办?可能玩得不好。

由于特定原因,这件东西的设计可能正是你想要的,但我不禁觉得它可能会更圆滑。据我所知,它的设计并没有真正考虑到线程。

【讨论】:

    猜你喜欢
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多