g_main_loop使用100%的CPU

时间:2015-04-11 18:12:15

标签: c++ multithreading glib gtkmm

我使用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分钟。

为什么会发生这种情况,有没有办法调试这个?

1 个答案:

答案 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()函数。

我不知道这是否是最好的方法,但它解决了这个问题。