【发布时间】:2017-06-11 12:53:27
【问题描述】:
在我的 GTK+ 应用程序中,GtkFileChooserWidget 的一个实例是永久可见的。通过选择文件(单击),用户可以处理文件。这是由回调函数 switch_file() 完成的。
g_signal_connect (chooser, "selection-changed", G_CALLBACK (switch_file), gs);
函数 switch_file() 有时会很慢,因为它在模式对话框中等待用户响应。除非删除当前在 FileChooser 中选择的文件(由应用程序本身或系统上的任何其他进程),否则一切正常。 FileChooser 显然在自己的线程中运行,然后提交对 switch_file() 的二次调用,这会导致混乱。我试图通过使用互斥锁来防止多次调用:
static void switch_file (GtkWidget *widget, gpointer data)
{
info_t *gs = data;
int err;
if ((err = pthread_mutex_lock (&gs->mutex)))
DebugExit ("pthread_mutex_lock(): %s", strerror (err));
/* ... */
}
但是,对回调函数的所有调用都是在同一个堆栈上的同一个线程中完成的。因此,对 pthread_mutex_lock() 的第二次调用失败(使用了 PTHREAD_MUTEX_ERRORCHECK_NP)并让进程退出。
是否有可能在 switch_file() 工作时推迟对回调函数的调用?对于用户事件(按键),它已经有效,但不适用于由删除文件并行引起的信号。
如果信号不能被推迟:收集所有选定文件并随后(在主线程中)处理它们的信号安全解决方案是什么?
【问题讨论】:
-
进入switch_file()时暂时断开信号?退出时重新连接?
-
您不能在多个线程上运行 GTK+。您必须将所有 GTK+ 内容限制在一个线程中。摆脱你的其他线程。错误的答案已经变得“显而易见”,这让我感到害怕。
-
@Chimera 断开信号将涉及丢失选择的一些更改。但是如果没有其他解决方案,我会试试这个。
-
@andlabs 我没有明确启动任何线程。显然,GtkFileChooserWidget 在单独的线程中运行。但是,我对此没有影响。
-
那我不确定你到底想解决什么问题...你想阻止用户在对话框打开时删除文件吗?为什么你在用户选择它们时处理选择,而不是在关闭对话框之后?
标签: c linux callback gtk signals