查詢超時呼叫和 GMainContext。這真的讓我很困惑
假設我有下面的代碼(有點不完整,只是為了演示)。我使用普通的 Pthreads 來創建一個執行緒。在執行緒中,我運行 Glib 功能并創建了一個 GMainContext(存盤在 l_app.context 中)。
然后我創建了一個源,以大約 1 秒的間隔迭代地運行函式 check_cmd。這個回呼(或者我們可以稱它為執行緒?)將檢查來自其他執行緒的命令(此處未顯示 Pthreads 以更新 cmd 狀態)。從這里開始,有兩個具體的命令
- 一開始回圈功能
- 另一個結束回圈功能
我已經完成并想到了兩種創建函式并將它們設定為迭代運行的方法。
- 創建另一個超時
- 使用創建 check_cmd 的相同方法
當我嘗試兩種方法時,對我來說基本上兩者基本上都是相同的方法。計劃 A(正如我所說的那樣)不起作用,但計劃 B ......實際上至少運行一次。所以我想知道如何解決它們...
或者也許我應該使用 g_source_add_child_source() 代替?
總之,我的問題是
- 當您創建一個新背景關系并將其推送為默認背景關系時,所有需要 main_context 的后續函式都會參考此背景關系嗎?
- 簡而言之,當一個回圈已經在運行時,你如何添加新的源,比如我的案例
- 最后,可以在您創建的回呼中退出主回圈嗎?
這是我的偽代碼
#include <glib.h>
#include <dirent.h>
#include <errno.h>
#include <pthread.h>
#define PLAN_A 0
typedef struct
{
GMainContext *context;
GMainLoop *loop;
}_App;
static _App l_app;
guint gID;
gboolean
time_cycle(gpointer udata)
{
g_print("I AM THREADING");
return true;
}
gboolean
check_cmd_session(NULL )
{
while(alive) /// alive is a boolean value that is shared with other threads(not shown)
{
if(start)
{
/// PLAN A
//// which context does this add to ??
#if PLAN_A
g_timeout_add_seconds(10, (GSourceFunc)timeout, NULL);
#else
/// or should i use PLAN B
GSource* source = g_timeout_source_new(1000);
gID = g_source_set_callback(source,
(GSourceFunc)time_cycle,
NULL,
NULL);
g_source_attach(source, l_app.context);
#endif
}
else
{
#if PLAN_A
g_source_remove(gID);
#else
}
}
g_main_loop_quit (l_app.loop);
return FALSE;
}
void*
liveService(Info *info)
{
l_app.context = g_main_context_new ();
g_main_context_push_thread_default(l_app.context);
GSource* source = g_timeout_source_new(1000);
g_source_set_callback(source,
(GSourceFunc)check_cmd_session,
NULL,
NULL);
/// make it run
g_source_attach(source, l_app.context);
g_main_loop_run (l_app.loop);
pthread_exit(NULL);
}
int main()
{
pthread_t tid[2];
int thread_counter = 0;
err = pthread_create(&(tid[thread_counter]), NULL, &live, &info);
if (err != 0)
{
printf("\n can't create live thread :[%s]", strerror(err));
}
else
{
printf("--> Thread for Live created successfully\n");
thread_counter ;
}
/**** other threads are build not shown here */
for(int i = 0; i < 2; i )
{
printf("Joining the %d threads \n", i);
pthread_join(tid[i],NULL);
}
return 0;
}
uj5u.com熱心網友回復:
總之,我的問題是
- 當您創建一個新背景關系并將其推送為默認背景關系時,所有需要 main_context 的后續函式都會參考此背景關系嗎?
記錄為使用執行緒默認主背景關系的函式將使用GMainContext最近推送的g_main_context_push_thread_default().
記錄為使用全域默認主背景關系的函式不會。他們將使用GMainContext在初始化時創建并與主執行緒相關聯的。
g_timeout_add_seconds()記錄為使用全域默認主背景關系。因此,如果您希望將超時源附加到特定的GMainContext.
- 簡而言之,當一個回圈已經在運行時,你如何添加新的源,比如我的案例
g_source_attach()在迭代主要背景關系時起作用。
- 最后,可以在您創建的回呼中退出主回圈嗎?
是的,g_main_loop_quit()可以隨時呼叫。
從您的代碼來看,您似乎并沒有GMainLoop為每個GMainContext人創建一個新的,而是假設一個人GMainLoop將以某種方式與GMainContext程序中的所有 s 一起作業。這是不正確的。如果你要使用GMainLoop,你需要為你創建的每一個創建一個新的GMainContext。
除了所有其他的事情,您可能會發現使用 GLib 的執行緒函式比直接使用 pthread 更容易。GLib 的執行緒函式可移植到其他平臺,并且更易于使用。鑒于您已經鏈接到 libglib,使用它們不會產生任何額外費用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/481896.html
