我正在使用 GTK 构建一个相当简单的C 应用程序,但必须执行一些阻塞 IO,这将触发对 GUI 的更新。为了做到这一点,我在此pthread
之前开始了一个新的权利gtk_main()
:
/* global variables */
GMainContext *mainc;
/* local variables */
FILE *fifo;
pthread_t reader;
/* main() */
mainc = g_main_context_default();
pthread_create(&reader, NULL, watch_fifo, argv[argc-1]);
gtk_main();
当pthread
读取一些数据时,它会像这样更新 GUI:
g_main_context_invoke(mainc, set_icon, param);
set_icon
在哪里
gboolean set_icon(gpointer data)
{
char *p = (char*)data;
gtk_status_icon_set_from_icon_name(icon, p);
return FALSE;
}
这在大多数情况下都有效,但我时不时地收到这个奇怪的错误消息:
[xcb] 处理队列时序列号未知 [xcb] 这很可能是一个多线程客户端并且 XInitThreads 没有被调用 [xcb] 中止,抱歉。 mktrayicon:xcb_io.c:274:poll_for_event:断言“!xcb_xlib_threads_sequence_lost”失败。
我认为使用的全部目的g_main_context_invoke
是避免线程问题?做了一些谷歌搜索,我遇到了gdk_threads_init
和gdk_threads_enter
朋友,但他们似乎都被弃用了?我知道 GTK 文档说所有 GUI 更新都应该在主线程上执行,但这并不能很好地与阻塞 IO 结合起来,而且我不希望在线程之间构建一些复杂的通信机制。
所以,我的问题是,我应该如何正确处理这个问题?
编辑:可以在这里看到完整的代码
EDIT2:作为基于@ptomato 答案的更新,我已经移至GThread
s 并使用了,如本次gdk_threads_add_idle()
提交中所见,但问题仍然存在。