2013-06-11 174 views
0

我試圖用線程來管理GTK +中的幾件事,但是,只要我嘗試在新線程中使用任何GUI函數,就會鎖定GUI,這是合理的,因爲GTK +不是線程安全。有沒有辦法解決?GTK +線程安全

這裏是我的代碼:

如果
int main(int argc, char *argv[]) 
{ 

GError *error = NULL; 

/* init threads */ 
g_thread_init(NULL); 
gdk_threads_init(); 

/* init gtk */ 
gtk_init(&argc, &argv); 

.... 

//Multithreaded functions 
g_thread_create(argument_thread, (gpointer)label7, FALSE, &error); 

gdk_threads_enter(); 
gtk_main(); 
gdk_threads_leave(); 
return 0; 
} 

void *argument_thread(void *args) 
{ 
    while(1) 
    { 
    gdk_threads_enter(); 
    gtk_entry_set_text(entry2,"random stuff"); 
    gdk_threads_leave(); 

    } 
} 
+2

'gdk_threads_enter'及其相關函數自版本3.6開始已棄用。您應該考慮通過閒置回調切換到主線程的傳播。有關詳細信息,請參見[關於此的文檔](https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk3-Threads.description)。 – user

回答

2

不知道這可能是一個問題(不知道GTK),但也許有一個競爭條件,如果線程獲取鎖的進入主循環開始前。

那麼你可以嘗試:

gdk_threads_enter(); 

//Multithreaded functions 
g_thread_create(argument_thread, (gpointer)label7, FALSE, &error); 

gtk_main(); 
gdk_threads_leave(); 

而且你應該拖延你的循環:

void *argument_thread(void *args) 
{ 
    while(1) 
    { 
     gdk_threads_enter(); 
     gtk_entry_set_text(entry2,"random stuff"); 
     gdk_threads_leave(); 

     sleep(10); 
    } 
} 
+0

謝謝! 當然更響應。 –

-1

我已經使用解決了這個問題g_timeoutég線程:http://www.freemedialab.org/wiki/doku.php?id=programmazione:gtk:gtk_e_i_thread

基本上我用3個功能,一個啓動線程,一個在沒有操作窗口小部件(線程)的情況下執行作業,另一種作爲超時定時器,每隔n秒檢查一次由線程編寫的某些值並更新「圖形界面」。

或者你可以使用 「g_idle_add」:http://www.freemedialab.org/wiki/doku.php?id=programmazione:gtk:gtk_e_i_thread#versione_con_g_idle_add

gdk_threads_enter()和gdk_threads_leave()從3.6版本的GTK棄用。

+0

說到C++中的Gtkmm(但這只是一個包裝,所以這些函數也存在於c或任何其他gtk中,我只是不知道它們的確切名稱)GLib提供了一個「Dispatcher」對象,您可以將一個函數連接到然後使用它位於不是GTK線程的線程中,並調用連接的函數,然後在GTK線程上下文中執行該函數,以便您可以在那裏使用GUI函數。我認爲這是一個非常漂亮的方法,尤其是因爲您不需要在後臺運行計時器。 – tagelicht