给定从用户连接到回调函数的信号,gtk_main 线程将休眠,直到发出信号。我搜索了有关如何或何时发出的详细信息,但找不到任何我不知道的信息。
更具体地说,它是异步发出的,以便我可以在某个函数中间调用信号,还是等待特定函数先返回?从 GThread 内发出“切换页面”信号(例如使用
gtk_notebook_remove_page()
)可能会产生奇怪的效果,因为事件发生在主线程中,并且我不能保证 gtk_notebook_remove_page()
在主上下文中执行,就好像 g_main_context_invoke()
一样被使用?但是,如果我在线程内手动发出带有 g_signal_emit()
的信号(如果信号可以通过这种方式发出)会怎样?
首先,gtk mainloop 不是线程安全的。从主循环以外的线程调用任何 gtk 函数都是 UB。
详细描述可以在here找到,但简而言之:主循环不会休眠或等待信号。它总是在迭代,如果它看到用户按下了按钮,它就会发出信号。
我个人使用此类函数,即 g_timeout_add'ed:
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;
}
编辑:稍后我发现,
g_idle_add
是线程安全的,因此可以重写该函数,而无需显式检查request_redraw
标志:
static void
callback_which_initiates_redraw (gpointer data)
{
MyObj *self = data;
g_idle_add (gtk_widget_queue_draw, self);
}
更具体地说,它是异步发出的,以便我可以在某个函数中间调用信号,还是等待特定函数先返回?
它等待着。当您处于主循环中时,没有什么是异步的。
从 GThread 内发出“switch-page”信号(例如使用 gtk_notebook_remove_page())可能会产生奇怪的效果,因为事件发生在主线程中,并且我不能保证 gtk_notebook_remove_page() 在主上下文中执行,就像 g_main_context_invoke( )被使用? 但是,如果我在线程内使用 g_signal_emit() 手动发出信号(如果信号可以通过这种方式发出)会怎样?
我不太明白这两个问题,但再说一遍:不从主循环调用 gtk 函数是 UB。