【问题标题】:GTK+ 3.0 in C on Linux: handle multiple calls of callback function by signalsLinux 上 C 语言 GTK+ 3.0:通过信号处理回调函数的多次调用
【发布时间】: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


【解决方案1】:

我发现最好的解决方案是忽略信号。我不确定以下解决方案是否绝对安全,但它确实有效。

static int switch_ignore = false;

static void switch_file (GtkWidget *widget, gpointer data)
{
   info_t *gs = data;

   if (switch_ignore)
      return;

   switch_ignore = true;

   /* Do some work on the file system. */

   switch_ignore = false;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多