2011-10-12 2 views
6

저는 DBus와 이벤트 기반 프로그래밍을 시작했습니다. 제가 만들고자하는 서비스는 세 부분으로 이루어져 있지만 두 부분은 실제로 "서버"입니다.Dbus/GLib 메인 루프, 백그라운드 스레드

1) 실제 DBus 서버는 HTTPS를 통해 원격 웹 사이트와 통신하고 세션을 관리하며 정보를 전달합니다.

2) 서비스의 다른 부분은이 클라이언트가 서비스에 대한 호출이 서비스에서 정보를 검색 할 수 있도록 외부 웹 사이트

3)에서 활성 세션을 유지하기 위해 2 분마다 살아 페이지를 계속 호출합니다.

몇 가지 간단한 예제 프로그램을 발견했습니다. 프로토 타입 # 1과 # 2에 적용하려고합니다. 두 가지 모두에 대해 별도의 프로그램을 작성하는 것이 아닙니다. 나는 그들이 하나의 두 스레드 프로세스로 실행할 수 있다고 생각했습니다.

내가보기에 문제는 내 keep alive 스레드에서 time.sleep (X)를 호출한다는 것입니다. 쓰레드는 잠들지 만 깨어나지 않습니다. GIL은 GLib 메인 루프에 의해 해제되지 않는다고 생각합니다.

가 여기 내 스레드 코드입니다 : 인쇄 문에서

class Keepalive(threading.Thread): 
    def __init__(self, interval=60): 
    super(Keepalive, self).__init__() 
    self.interval = interval 
    bus = dbus.SessionBus() 
    self.remote = bus.get_object("com.example.SampleService", "/SomeObject") 

    def run(self): 
    while True: 
     print('sleep %i' % self.interval) 
     time.sleep(self.interval) 
     print('sleep done') 
     reply_status = self.remote.keepalive() 
     if reply_status: 
      print('Keepalive: Success') 
     else: 
      print('Keepalive: Failure') 

, 나는 잠이 시작될 것을 알고,하지만 난 볼 수 없습니다 "잠이 다."

if __name__ == '__main__': 
try: 
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 

    session_bus = dbus.SessionBus() 
    name = dbus.service.BusName("com.example.SampleService", session_bus) 
    object = SomeObject(session_bus, '/SomeObject') 

    mainloop = gobject.MainLoop() 

    ka = Keepalive(15) 
    ka.start() 
    print('Begin main loop') 
    mainloop.run() 
except Exception as e: 
    print(e) 
finally: 
    ka.join() 

일부 다른 관찰 :

다음은 주요 코드

나는 "메인 루프를 시작합니다"라는 메시지가, 그래서 그것을 통제를 점점 알고있다. 그런 다음, "sleep % i", 그리고 그 이후에는 아무 것도 볼 수 없습니다.

I^C이면 "잠든 것"이라고 표시됩니다. 20 ~ 초 후에, 나는 self.run에서 예외가() 원격 응용 프로그램이 응답하지 않았다 :

DBusException : org.freedesktop.DBus.Error.NoReply을 : 회신을받지 못했습니다. 가능한 원인은 다음과 같습니다. 원격 응용 프로그램이 회신을 보내지 않았거나 메시지 버스 보안 정책이 회신을 차단했거나 회신 제한 시간이 만료되었거나 네트워크 연결이 끊어졌습니다.

서버 내에서 활성 유지 코드를 실행하는 가장 좋은 방법은 무엇입니까?

덕분에,

답변

6

당신은 gobject.threads_init()를 호출하여 gobject를 사용하는 경우 명시 적으로 멀티 스레딩을 활성화해야합니다. 배경 정보는 PyGTK FAQ을 참조하십시오.

다음으로 설명하는 목적을 위해 타임 아웃이 더 적합 할 것 같습니다. 다음과 같이 사용

# Enable timer 
self.timer = gobject.timeout_add(time_in_ms, self.remote.keepalive) 
# Disable timer 
gobject.source_remove(self.timer) 

이것은 keepalive 기능마다 time_in_ms (밀리) 초를 호출합니다. 자세한 내용은 PyGTK reference에서 다시 확인할 수 있습니다.

+0

Jro, 제안 해 주셔서 감사합니다. 나는 이것에 익숙하지 않고 실제로 dbus/glib/gtk/gobject 사이의 관계를 이해하지 못했습니다. tomeout_add()는 내가 원하는 것입니다. – fandingo