Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ g_主循环使用100%CPU_C++_Multithreading_Glib_Gtkmm - Fatal编程技术网

C++ g_主循环使用100%CPU

C++ g_主循环使用100%CPU,c++,multithreading,glib,gtkmm,C++,Multithreading,Glib,Gtkmm,我已经使用glibmm构建了我的第一个应用程序。我使用了很多线程,因为它需要大量的处理。我已尝试遵循有关多线程的指导原则,即不从运行g_main_loop的线程以外的其他线程进行任何GUI更新 我在工作线程中进行了大量的图形渲染,但我总是只更新一个PixBuf,它随后由来自主循环的_draw()上的小部件绘制 只要我渲染的数据是从文件中读取的,一切都很好。当我开始从定期渲染的服务器流式传输数据时,问题就开始了 偶尔,尤其是在同时执行应用程序的多个实例时,我会发现主线程占用100%的CPU时间。在

我已经使用glibmm构建了我的第一个应用程序。我使用了很多线程,因为它需要大量的处理。我已尝试遵循有关多线程的指导原则,即不从运行
g_main_loop
的线程以外的其他线程进行任何GUI更新

我在工作线程中进行了大量的图形渲染,但我总是只更新一个
PixBuf
,它随后由来自主循环的_draw()上的小部件
绘制

只要我渲染的数据是从文件中读取的,一切都很好。当我开始从定期渲染的服务器流式传输数据时,问题就开始了

偶尔,尤其是在同时执行应用程序的多个实例时,我会发现主线程占用100%的CPU时间。在进程上运行strace显示
g\u main\u循环
已在一个调用
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分钟


为什么会发生这种情况?有什么方法可以调试这种情况吗?

我的错误是,我从一个工作线程调用了
queue\u draw()
。考虑到函数名为“queue”,我假设它将对重绘进行排队,稍后将由
g\u main\u循环执行。事实证明,这就是打破g_main_循环的原因。我希望
libgtkmm
在其参考手册中对这些多线程限制有更详细的介绍

我的解决方案是将
Glib::Dispatcher queueRedraw
添加到我的小部件中,并将其连接到
queue\u draw()
函数:

queueRedraw.connect(sigc::mem\u fun(*this,&MyWidgetClass::queue\u draw))

调用
queueRedraw()
向主线程发出调用
queue\u draw()函数的信号


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

连接一个调试器(比如
gdb
),为
poll
创建一个断点,等待它,收集回溯(
bt
gdb
中),现在想想为什么在第一次调用
poll
)place@myaut,我从未用GDB解决过这个问题。为什么从另一个线程调用
queue\u draw()
就导致了
g\u main\u loop
的崩溃,我仍然无法理解,如果允许的话,这会更有意义,因为它不是真正的GUI更新,只是排队等待GUI更新。