在我的GUI中,我在主窗口中有一個列表存儲樹視圖。當用戶雙擊一行時,彈出一個對話框。問題是我在對話框中填充的數據需要一段時間來處理,所以我所做的是啓動一個線程(使用boost線程)來執行對話框計算。GTK中線程的死鎖問題
In main:
.......
g_signal_connect (G_OBJECT (m_treeview), "row_activated", G_CALLBACK (m_row_activated),
(gpointer) main_window);
.......
In m_row_activated:
.........
// combo_box and dialog are GtkWidget* global variables
create_dialog(dialog, combo_box); // function creates the combobox
set_combo_box_with_loading_message;
gtk_widget_show_all (dialog);
thread m_thread (bind (&do_dialog_calculations, data1, data2, combobox));
.........
In do_dialog_calculations:
.........
// do_calculations takes about 15 seconds to complete
do_calculations(MyData data1, MyData data2, combobox);
gdk_threads_enter();
gtk_combo_box_append_text(...);
gdk_threads_leave()
一切工作正常(即當用戶雙擊一排,一個對話框的加載消息立即彈出,並最終被填充在線程返回時),但我的問題是當用戶關閉該對話框do_dialog_calculations中的do_calculations完成之前。如果對話框被銷燬,我的組合框內的組合框將被銷燬,並且我對gtk_combo_box_append_text的調用將會發生故障。
我試圖更新前測試組合框:
In do_dialog_calculations:
.........
do_calculations(MyData data1, MyData data2, combobox);
gdk_threads_enter();
if (GTK_IS_COMBO_BOX (combobox))
gtk_combo_box_append_text(...);
gdk_threads_leave()
但這會導致死鎖在調用GTK_IS_COMBO_BOX。我認爲這是GTK_IS_COMBO_BOX可能調用gdk_threads_enter()的原因。我也嘗試過測試NULL
if (combobox == NULL)
但這似乎並不奏效。有關如何解決此問題的任何建議?
更新:在GTK_IS_COMBO_BOX發生死鎖時,如果我在打開對話框後立即關閉對話框(即在do_calculations()之前完成),如果我只是讓對話框坐下來,它最終會更新;另外,如果我切換組合框寫調用gdk_threads_enter()之前。
if (GTK_IS_COMBO_BOX (combobox)
{
gdk_threads_enter();
gtk_combo_box_append_text(...);
gdk_threads_leave();
}
當我摧毀的對話框代碼執行之前不會發生死鎖但是,我怕罕見的可能性GTK_IS_COMBO_BOX檢查完成後,用戶將關閉對話框。
PS - 我使用線程來做我的對話框計算,因爲對話框是非模態的,我希望用戶能夠在對話框填充時用主UI做其他事情。
感謝asveikau快速回復!我在調用gtk_main()之前調用g_thread_init和gdk_threads_init: g_thread_init(NULL); gdk_threads_init(); gtk_init(&的argc,&argv); ....... gdk_threads_enter(); gtk_main()函數; gdk_threads_leave(); 有趣的是,當我破壞GTK_IS_COMBO_BOX之前的對話框,檢查死鎖只發生。例如,當我雙擊一行時,彈出對話框(大約15秒後),但是如果我雙擊該行並立即銷燬對話框,它會掛在GTK_IS_COMBO_BOX檢查上 – Tim
@Tim - 讀你的評論我想我看到了另一個問題,我已經更新了答案。 – asveikau
感謝asveikau爲您提供的所有幫助!您的解決方案奏效。 – Tim