g_main_context_invoke 사용법 문의 및 개선 방법 문의
안녕하세요.
g_main_context_invoke 사용 문의가 있어서 질문 드립니다.
현재
X 란 daemon 있고, Y 란 so 라이브러리가 있습니다.
X 에서 Y 의 function A를 호출을 하는데,
A의 수행시간이 너무 오래 걸려서, 별도의 thread를 생성해서 수행하는 방법을 찾아보고 있습니다.
A란 function은 대충 아래와 같이 되어 있습니다.
int A (callback)
{
...
...
...
g_main_context_invoke(NULL, _functionA, callback);
return true;
}
지금 문제는 1 이란 데몬에서 A를 호출하면 A가 return 하기까지 시간이 너무 오래 걸리는게 문제 입니다.
(dbus 등록 및 다른 initialize 작업 등등.. 이부분의 개선은 현재 힘든 상황입니다.)
개선을 좀 하고 싶은데,
1. g_main_context_invoke 를 하게 되면 정확하게 어떻게 되는지 ??
2. 아래와 같이 바꿔 봤는데, 제대로 동작을 안 하더군요.
X에 서 A를 호출하던것을 A1 을 호출하도록 수정을 하고,
A1에서 idle add를 하도록 바꿔봤는데
int A1(callback)
{
g_idle_add(A, callback);
return true;
}
이렇게 바꿨더니
g_main_context_invoke(NULL, _functionA, callback); 이 코드 때문인지
A란 function이 종료가 되지 않더군요..;;
해당 문제를 어떻게 좀 개선할 수 있을까요??
(원하는 것은 현재 A란 function의 수행시간을 단축을 하기는 힘들어서,
별도의 thread 생성등을 통해서 X에서 A를 호출하고 최대한 적게 기다리면서 다음 과정을 하고 싶습니다.)
고수님들의 조언 부탁드립니다.
g_main_context_invoke()는 해당 함수 주석을 보면 어떤일을 하는지 알 수 있습니다.
g_main_context_invoke()를 호출하면 정확히 어떻게 되는지는 아래 주석을 보면 이해하실 수 있을거에요.
/**
* g_main_context_invoke:
* @context: (allow-none): a #GMainContext, or %NULL
* @function: function to call
* @data: data to pass to @function
*
* Invokes a function in such a way that @context is owned during the
* invocation of @function.
*
* If @context is %NULL then the global default main context — as
* returned by g_main_context_default() — is used.
*
* If @context is owned by the current thread, @function is called
* directly. Otherwise, if @context is the thread-default main context
* of the current thread and g_main_context_acquire() succeeds, then
* @function is called and g_main_context_release() is called
* afterwards.
*
* In any other case, an idle source is created to call @function and
* that source is attached to @context (presumably to be run in another
* thread). The idle source is attached with #G_PRIORITY_DEFAULT
* priority. If you want a different priority, use
* g_main_context_invoke_full().
*
* Note that, as with normal idle functions, @function should probably
* return %FALSE. If it returns %TRUE, it will be continuously run in a
* loop (and may prevent this call from returning).
*
* Since: 2.28
**/
그리고 위 함수의 내부 코드를 보면 g_main_context의 owner가 g_thread_self인지 검사후 하는일이 달라지게 됩니다.
if (g_main_context_is_owner (context))
{
while (function (data));
if (notify != NULL)
notify (data);
}
else
{
...
}
그리고, idler의 경우 timing에 영향을 받을 수 있는 상황에서는 심각한 문제상황을 만들 수도 있습니다.
(예: 초기화 등의 역할을 수행하는 함수에서 시간이 걸리는 부분을 ilder로 분리하고 먼저 리턴 시켰을 경우, idler에 의해 호출되는 함수는 mainloop 상황에 따라 호출이 결정되기 때문에 언제 호출될지 보장을 못함.)
댓글 달기