glib, gmainloop, gik
gmainloop 다룰 때,,, 어디선가 본 영문판 글을 번역기에 돌린 내용이다.
기술
메인 이벤트 루프는 GLib 및 GTK + 어플리케이션에 사용 가능한 모든 이벤트 소스를 관리합니다. 이러한 이벤트는 파일 설명자 (일반 파일, 파이프 또는 소켓) 및 시간 초과와 같은 여러 유형의 소스에서 비롯 될 수 있습니다. 새로운 유형의 이벤트 소스는 g_source_attach ()를 사용하여 추가 할 수도 있습니다.
복수의 독립 소스 세트가 다른 thread로 처리되도록 (듯이)하기 위해서, 각 소스는 GMainContext에 관련 지을 수 있습니다. GMainContext는 단일 스레드에서만 실행될 수 있지만 소스를 추가하고 다른 스레드에서 소스를 제거 할 수 있습니다.
각 이벤트 소스에는 우선 순위가 지정됩니다. 기본 우선 순위 인 G_PRIORITY_DEFAULT는 0입니다. 0보다 작은 값은 우선 순위가 높음을 나타냅니다. 0보다 큰 값은 우선 순위가 낮습니다. 우선 순위가 높은 소스의 이벤트는 우선 순위가 낮은 소스의 이벤트보다 먼저 처리됩니다.
유휴 기능을 추가하고 우선 순위를 지정할 수도 있습니다. 우선 순위가 높은 이벤트가 처리 될 준비가 될 때마다 실행됩니다.
GMainLoop 데이터 유형은 메인 이벤트 루프를 나타냅니다. GMainLoop은 g_main_loop_new ()로 생성됩니다. 초기 이벤트 소스를 추가 한 후 g_main_loop_run ()이 호출됩니다. 이렇게하면 각 이벤트 소스의 새 이벤트를 계속 확인하고 디스패치합니다. 마지막으로 소스 중 하나의 이벤트를 처리하면 g_main_loop_quit ()을 호출하여 기본 루프를 종료하고 g_main_loop_run ()이 반환됩니다.
재귀 적으로 GMainLoop의 새로운 인스턴스를 생성하는 것이 가능합니다. 이것은 모달 대화 상자를 표시 할 때 GTK + 응용 프로그램에서 자주 사용됩니다. 이벤트 소스는 특정 GMainContext와 연관되어 있으며 해당 GMainContext와 연결된 모든 주 루프에 대해 검사되고 전달됩니다.
GTK +에는 이러한 함수 중 일부의 래퍼가 들어 있습니다. gtk_main (), gtk_main_quit () 및 gtk_events_pending ().
새 소스 유형 만들기
GMainLoop 기능의 특이한 기능 중 하나는 내장 소스 유형의 이벤트 소스 외에도 새로운 유형의 이벤트 소스를 생성하여 사용할 수 있다는 것입니다. 새 이벤트 소스 유형은 GDK 이벤트를 처리하는 데 사용됩니다. GSource 구조체로부터 「파생」에 의해 새로운 소스 형이 작성됩니다. 파생 된 소스 유형은 첫 번째 요소로 GSource 구조 및 새 소스 유형에 고유 한 기타 요소가있는 구조로 표시됩니다. 새 소스 유형의 인스턴스를 작성하려면 파생 된 구조의 크기와 함수 테이블을 전달하는 g_source_new ()를 호출하십시오. 이러한 GSourceFuncs는 새로운 소스 유형의 동작을 결정합니다.
새로운 소스 유형은 기본적으로 두 가지 방식으로 주 컨텍스트와 상호 작용합니다. GSourceFuncs의 준비 기능은 타임 아웃을 설정하여 주 루프가 소스를 다시 검사하기 전에 대기하는 최대 시간을 결정할 수 있습니다. 또한 소스는 g_source_add_poll ()을 사용하여 기본 컨텍스트가 검사하는 파일 설명자를 집합에 추가 할 수 있습니다.
메인 루프 반복 커스터마이징
GMainContext의 단일 반복은 g_main_context_iteration ()을 사용하여 실행할 수 있습니다. 어떤 경우에는, 예를 들어, GMainLoop을 외부 메인 루프와 통합 할 때, 메인 루프의 세부 사항이 정확히 어떻게되는지에 대한보다 상세한 제어가 필요합니다. 이러한 경우 g_main_context_iteration ()의 구성 요소 기능을 직접 호출 할 수 있습니다. 이 함수는 g_main_context_prepare (), g_main_context_query (), g_main_context_check () 및 g_main_context_dispatch ()입니다.
주 컨텍스트의 상태
이 기능의 작동은이 그림에서와 같이 상태 도표를 통해 가장 잘 볼 수 있습니다.
UNIX에서 GLib mainloop은 fork ()와 호환되지 않습니다. mainloop을 사용하는 프로그램은 mainloop으로 돌아 가지 않고 자식에서 exec () 또는 exit ()해야합니다.
소스의 메모리 관리
호출시에 콜백에 건네 질 GSource에 건네진 사용자 데이터의 메모리 관리에는, 2 개의 옵션이 있습니다. 이 데이터는 g_timeout_add (), g_timeout_add_full (), g_idle_add () 등의 호출에서 제공되며보다 일반적으로 g_source_set_callback ()을 사용하여 제공됩니다. 이 데이터는 일반적으로 위젯이나 네트워크 프로토콜 구현과 같은 시간 초과 또는 유휴 콜백을 '소유'하는 객체입니다. 많은 경우,이 소유 객체가 파괴 된 후에 콜백이 호출되어 해제 된 메모리를 사용하기 때문에 오류가 발생합니다.
첫 번째 옵션은 g_timeout_add () 또는 g_source_attach ()와 같은 함수에서 반환 된 소스 ID를 저장하고 소유 객체가 완성되었을 때 g_source_remove ()를 사용하여 주 컨텍스트에서 해당 소스를 명시 적으로 제거하는 것입니다. 이렇게하면 객체가 아직 살아있는 동안에 만 콜백을 호출 할 수 있습니다.
두 번째 옵션은 콜백의 객체에 대한 강력한 참조를 유지하고 콜백의 GDestroyNotify에서이를 해제하는 것입니다. 이렇게하면 소스가 최종화 될 때까지 객체가 활성 상태로 유지되고 최종 시간 동안 객체가 호출 된 후 보장됩니다. GDestroyNotify는 GSource 함수의 '전체'변형 (예 : g_timeout_add_full ())에 전달되는 또 다른 콜백입니다. 소스가 fi 일 때 호출됩니다.
기타 링크들
Node-js event loop
https://nikhilm.github.io/uvbook/eventloops.html
https://github.com/mzabaluev/glib-uv/blob/master/glib-uv.c
https://curl.haxx.se/mail/lib-2015-07/att-0049/multi-app.cpp
http://www.lanedo.com/the-main-loop-the-engine-of-a-gui-library/
https://www.avahi.org/doxygen/html/glib-integration_8c-example.html