我使用glibmm构建了我的第一个应用程序。我使用了很多线程,因为它处理繁重。我试图遵循有关多线程的指导原则,即不从其他线程执行任何GUI更新,而不是运行g_main_loop
的线程。
我在工作线程中进行了大量的图形渲染,但我总是只更新一个PixBuf
,后来由主循环中的小部件on_draw()
绘制。
只要从文件中读取我呈现的数据,一切都很好。当我开始从我定期渲染的服务器传输数据时,问题就开始了。
时不时地,尤其是在同时执行我的应用程序的多个实例时,我发现主线程需要100%的CPU时间。在流程上运行strace会显示g_main_loop
已经在一个永久循环中调用poll
:
poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=10, events=POLLIN}, {fd=8, events=POLLIN}], 4, 100) = 1 ([{fd=10, revents=POLLIN}])
在proc中我得到了文件描述符10:10 -> socket:[1132750]
轮询总是立即返回,因为文件描述符10可以提供。这种情况永远存在,所以我假设永远不会读取文件描述符。奇怪的是,运行5个应用程序几乎总是会导致所有5个应用程序在几分钟之后在无限轮询循环中结束,而仅运行实例1似乎在我尝试的大多数时间内工作超过30分钟。
为什么会发生这种情况,有没有办法调试这个?
答案 0 :(得分:2)
我的错误是我从我的一个工作线程中调用了queue_draw()
。鉴于该函数被调用" queue",我假设它会对重绘进行排队,稍后将由g_main_loop
执行。事实证明,这是打破g_main_loop
的原因。我希望libgtkmm
在其参考手册中有更多关于这些多线程限制的细节。
我的解决方案,问题是将Glib::Dispatcher queueRedraw
添加到我的Widget并将其连接到queue_draw()
函数:
queueRedraw.connect(sigc::mem_fun(*this, &MyWidgetClass::queue_draw))
调用queueRedraw()
表示主线程调用queue_draw()
函数。
我不知道这是否是最好的方法,但它解决了这个问题。