2009-08-13 4 views
0

기본적으로 DeviceAdded DBus 이벤트 (예 : 누군가 USB 드라이브를 꽂을 때)를 수신하는 Python 프로그램이 있고 이벤트가 발생하면 메타 데이터를 수집하는 스레드를 만들고 싶습니다 새롭게 연결된 장치에. 그러나이 작업을 비동기 적으로 수행하려고합니다. 즉, 하나의 스레드가 장치에서 메타 데이터 수집을 유지하면서 부모에게 제어를 반환하는 동안 이러한 이벤트를 계속 수신 할 수 있습니다. 지금은 컬렉션이 완료 될 때까지 스레드가 차단됩니다. 여기에 내 코드의 샘플입니다Python 스레딩 질문 - 부모에게 컨트롤 반환

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를 전혀 사용하지 않았으며 실제로 테스트 할 수는 없다는 것을 명심하십시오.

또한 사용자가 정의한대로 응용 프로그램을 사용하여 스레드에서 수행하는 것이 좋지 않은 캡처 기능에서 사용자 입력을 얻으려고합니다. 첫 번째 프롬프트가 화면에 표시된 상태에서 두 번째 장치가 연결되면 어떻게됩니까? 멋지게 놀지 않을 수도 있습니다.

이 물건의 디자인은 당신이 특정한 이유로 그것을 원했던 방식 일지 모르지만 나는 그것이 더 매끄러운 것처럼 느낄 수는 없습니다. 내가 실제로 말할 수있는 것을 염두에두고 설계된 것은 아닙니다.