【发布时间】:2011-08-21 18:50:29
【问题描述】:
在我的 GUI 中,我的主窗口中有一个列表存储树视图。当用户双击一行时,会弹出一个对话框。问题是我在对话框中填充的数据需要一段时间来处理,所以我所做的是启动一个线程(使用 boost 线程)来进行对话框计算。
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 执行其他操作。
【问题讨论】: