C GTK信号何时发出

C GTK信号何时发出,c,gtk,signals,C,Gtk,Signals,给定一个从用户连接到回调函数的信号,gtk_主线程将休眠,直到发出该信号。我搜索了它如何或何时发射的详细信息,但找不到任何我不知道的信息 更具体地说,它是异步发出的,这样我就可以在某个函数的中间调用信号,还是等待特定函数返回第一个函数?从GThread内发出“切换页面”信号(例如使用gtk_notebook_remove_page())可能会产生奇怪的效果,因为事件发生在主线程中,我不能保证gtk_notebook_remove_page()在主上下文中执行,就好像使用了g_main_conte

给定一个从用户连接到回调函数的信号,gtk_主线程将休眠,直到发出该信号。我搜索了它如何或何时发射的详细信息,但找不到任何我不知道的信息


更具体地说,它是异步发出的,这样我就可以在某个函数的中间调用信号,还是等待特定函数返回第一个函数?从GThread内发出“切换页面”信号(例如使用

gtk_notebook_remove_page()
)可能会产生奇怪的效果,因为事件发生在主线程中,我不能保证
gtk_notebook_remove_page()
在主上下文中执行,就好像使用了
g_main_context_invoke()
?但是,如果我在线程内部使用
g\u signal\u emit()
手动发出信号(如果信号可以通过这种方式发出),该怎么办?

首先,gtk mainloop不是线程安全的。从mainloop以外的线程调用任何gtk函数都是非常困难的

可以找到详细的描述,但简而言之:mainloop不睡眠或等待信号。它总是在迭代,如果它看到用户按下一个按钮,它就会发出一个信号

就我个人而言,我使用这类函数,它们是g_timeout_添加的:

static gboolean
redrawer (gpointer data)
{
   MyObj *self = data;

   if (g_atomic_int_get (&self->priv->request_redraw)
     gtk_widget_queue_draw (GTK_WIDGET (self));

  return G_SOURCE_CONTINUE;
}
Edit:过了一会儿我发现,
g\u idle\u add
是线程安全的,因此可以重写此函数,而无需显式检查
request\u redraw
标志:

static void
callback_which_initiates_redraw (gpointer data)
{
   MyObj *self = data;
   g_idle_add (gtk_widget_queue_draw, self);
}

更具体地说,它是异步发出的,这样我就可以在某个函数的中间调用信号,还是等待特定函数返回第一个?

它等待着。当您在主循环中时,没有什么是异步的

从GThread内发出“切换页面”信号(例如使用gtk_notebook_remove_page())可能会产生奇怪的效果,因为事件发生在主线程中,我不能保证gtk_notebook_remove_page()在主上下文中执行,就像使用g_main_context_invoke()一样? 但是,如果我在线程内部使用g_signal_emit()手动发出信号(如果信号可以通过这种方式发出),会怎么样

我不太明白这两个问题,但再一次:不是从mainloop调用gtk函数是UB