2010-01-28 5 views
1

emit을 통해 신호를 디스패치하기 위해 glib를 사용할 때 모든 리스너/핸들러가 연속적으로 또는이라고 불리우는 컨트롤은 각 리스너/핸들러 다음에 이벤트 루프에 넘겨 줄 수 있습니까?은 glib 신호가 비동기입니까?

답변

4

콜백은 모두 주 루프에 대한 제어권을 양도하지 않고 연속적으로 호출됩니다.

실제로 내가 아는 한, g_signal_emit()은 모든 핸들러가 호출 될 때까지 제어를 반환하지 않기 때문에 메인 루프가 시작될 기회가 없습니다.

이 글의 제목에 대한 질문에 대답하려면 : 아니오, glib 신호는 비동기 적이 지 않습니다.

0

GLib 신호는 동 기적 또는 비동기 적으로 처리 할 수 ​​있습니다. G 객체 신호는 항상 동기식입니다. 즉, 신호를 내 보내면 신호가 처리 될 때까지 신호가 반환되지 않습니다. 신호를 비동기 적으로 GLib로 처리하려면 (vala를 사용하여 코드를 일반 C로 변환하는 vala 컴파일러 사용) 신호 소스를 정의하거나 미리 정의 된 소스를 정의해야합니다 (예 : IdleSource 또는 TimeoutSource I/O가 문제가 될 때). 예를 들어 당신이 함수

void my_func() { 
    stdout.puts("Hello world! (async)\n"); 
} 

가 있다고 가정하고 (! 동일한 스레드에서) 비동기 적으로 호출하려면 여기를

void caller() { 
    // Here you want to insert the asynchronous call 
    // that will be invoked AFTER caller has returned. 
    // Body of caller follows: 
    stdout.puts("Hello world!\n"); 
} 

에서 원하는이다 당신은 그것을 할 방법 :

void caller() { 
    // Code for the asynchronous call: 
    var ev = new IdleSource(); 
    ev.set_callback(() => { 
    my_func(); 
    return Source.REMOVE; // Source.REMOVE = false 
    }); 
    ev.attach(MainContext.default()); 
    // Body of caller follows: 
    stdout.puts("Hello world!\n"); 
} 

다음과 같은 결과가 나옵니다.

Hello world! 
Hello world! (async) 

MainLoop이 유휴 상태 일 때 my_func() 함수가 실행됩니다. 처리 할 다른 신호가 없음). 특정 시간 간격이 경과 한 후에 트리거하려면 TimeoutSource 신호 소스를 사용하십시오. MainLoop이 실행 중이어야합니다. 그렇지 않으면 작동하지 않습니다.

문서 :

관련 문제