2014-10-03 2 views
0

문제가 생겼습니다 : 내 메인 스레드가 시작되어 약 10-15 초 실행해야하는 스레드에 참여해야합니다.GObject.idle_add(), thread.join() 및 내 프로그램이 응답하지 않습니다.

그래서 : 메인 스레드가 필요합니다 :

  • 메인 스레드는
  • 메인 스레드가 하위 스레드
  • 을 조인 10 ~ 15 초 정도 실행하는 자식 스레드, 시작 자식 스레드의 결과
  • 자식 스레드가 실행되는 동안 GUI를 업데이트했습니다, 그냥 진행률 표시 줄입니다 (매 0.2 초)
  • GUI를 업데이트 : 나는 재귀 함수를
  • 자식 스레드 완료를 사용합니다 메인 스레드는 결과를 얻을 수

내 코드의 문제점은 Trovarete_Window가 나타나고 시작이다 작업자 기능이 이미 종료 된 경우에만 업데이트하십시오.. 그래서 내 프로그램은 노동자가 달릴 때까지 멈추거나 멈춘다.

def collega_GUI(widget, args=()): 

    builder.get_object('Trovarete_Window').show_all() 
    progressbar.set_pulse_step(0.20) 

    pulse() 
    t = threading.Thread(target=worker) 
    t.setDaemon(True) 
    t.start() 
    t.join() 
    print 'a' 


def pulse(): 

    if not event.is_set(): 
     progressbar.pulse() 
     GObject.timeout_add(300, pulse) 


def worker(): 
    #hard work 
+0

어디에서 'collega_GUI'가 호출 되었습니까? 메인 루프는 어디에서 시작 했습니까? – dano

+0

또한 메인 스레드가 완료 될 때까지 차단해야하는'worker'에서 필요한 것은 무엇입니까? 실제 프로그램이 실제로 작업 스레드에서 결과를 얻는 방법은 무엇입니까? – dano

+0

1) collega_gui는 Gtk.Button에서 호출됩니다. 2) 하위 스레드가 끝에 도달하면 결과와 함께 변수를 설정합니다. 변수는 join() 다음에 호출되는 함수에 의해 리턴됩니다. – FrancescoN

답변

1

문제는 당신이 collegea_GUI 내부 t.join()를 호출하고 있다는 것입니다 :

여기 내 코드입니다. t.join()을 호출하면 주 스레드 (이벤트 루프를 실행하는 스레드)가 worker이 완료 될 때까지 차단됩니다. collegea_GUI 내부에서 차단되는 한 주 루프를 실행할 수 없습니다. 예약 한 pulse에 대한 호출을 실행할 수 없으며 GUI를 업데이트 할 수 없습니다.

t.join()을 호출하는 대신 pulse과 비슷한 작업을 수행해야합니다. 실행할 함수를 예약하여 worker이 완료되었는지 확인합니다. 다음과 같은 것 :

def collega_GUI(widget, args=()): 

    builder.get_object('Trovarete_Window').show_all() 
    progressbar.set_pulse_step(0.20) 

    pulse() 
    t = threading.Thread(target=worker) 
    t.setDaemon(True) 
    t.start() 
    wait_for_t(t) 

def wait_for_t(t): 
    if not t.is_alive(): 
     t.join() # This won't block, since the thread isn't alive anymore 
     print 'a' 
     # Do whatever else you would do when join() (or maybe collega_GUI?) returns 
    else: 
     Gobject.timeout_add(200, wait_for_t, t) 
+0

답장을 보내 주셔서 감사합니다.하지만 한 가지 문제가 있습니다. 나머지 코드는 wait_for_t 안에 넣을 수 없습니다. collega_GUI 내 주요 스레드입니다, 그것은 모든 데이터 구조를 가지고 있습니다. 나는 아직도 사소한 문제가 있다고 생각한다. (나는 생각한다) – FrancescoN

+0

업데이트 : 나는 다른 방법을 찾지 못했다. – FrancescoN

관련 문제