基本上,我有一个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()
任何想法都会非常感激:)我已经排除了导入列表以节省空间
答案 0 :(得分:2)
通过将_filter()
函数中的以下行更改为:
if device.QueryCapability("volume"):
threading.start_new_thread(self.capture, (device))
这假设大部分工作都在capture()
函数中进行。如果没有,那么只需稍早产生线程,可能在整个_filter()
函数上。
然后,这应该为检测到的每个过滤设备生成一个新线程。请记住,我没有做任何dbus的东西,不能真正测试这个,但这是一个想法。
此外,您正在尝试从捕获函数获取用户输入,使用您定义的应用程序,在线程中执行并不是一件好事。如果在第一个提示仍在屏幕上时连接了第二个设备怎么办?可能打得不好。
这件事的设计可能正是出于特定原因你想要它的方式,但我不禁觉得它可能会更加光滑。从我能说的内容来看,它并没有真正考虑到线程。