Qt application running with high CPU usage on Mac OS X
-
wrote on 29 May 2012, 13:23 last edited by
Hello.
I am currently maintaining an application that is designed to run on Mac OS X 10.4 through 10.7. It is a C++ application using Qt 3.3.8 (the commercial version) and Carbon. We are, at the moment, locked into using QT 3.3.8 (unless that's where the problem is, and then I guess we are not).
While it runs, Activity Monitor shows it using anywhere from 40% to 99% of the CPU. (I have reproduced this issue both on a Mac-Mini and a Macbook Pro.)
Its design is simple in that it checks for other instances of itself running. If none are found, it proceeds to connect to a remote service via a TCP/IP socket, set up messages and register message handlers, and ultimately enter into an event loop. This is all accomplished in the main thread, and it is single threaded.
Here is a select portion of the code. The ClientApplication class inherits from QtSingleApplication. I have left out a good portion, but I've tried to include what I deem appropriate. If you would like to see more, just ask.
@
ClientApplication app(argc, argv, &clientPrefs);
if (app.isRunning())
return 0;
app.initialize();
.
.
.
QMenuBar menuBar(0, "menubar");QPopupMenu* popupMenu = new QPopupMenu(0);
popupMenu->insertItem("About", mainWindow, SLOT(showAboutInfo()));
popupMenu->insertItem("Quit", mainWindow, SLOT(stopClient()));QApplication::connect(qApp, SIGNAL(aboutToQuit()), &printerConnector, SLOT(onTerminate()));
menuBar.insertItem("File", popupMenu);int returnValue = app.exec();
.
.
.
cleanup();
return returnValue;
@Here is the output from a time profile using Shark.
(Heavy View)
SharkProfileViewer
Generated from the visible portion of the outline view8.3%, ml_set_interrupts_enabled, mach_kernel
7.4%, lck_mtx_unlock_darwin10, mach_kernel
7.3%, lo_mach_scall, mach_kernel
-
5.8%, lck_mtx_lock, mach_kernel
-
5.4%, mach_msg_trap, libSystem.B.dylib
-
4.8%, __spin_lock, libSystem.B.dylib
-
2.0%, __CFRunLoopRun, CoreFoundation
-
1.9%, CFBasicHashGetBucket, CoreFoundation
-
1.7%, pthread_mutex_lock, libSystem.B.dylib
-
1.6%, inval_copy_windows, mach_kernel
-
1.5%, mach_msg, libSystem.B.dylib
-
1.3%, pthread_mutex_unlock, libSystem.B.dylib
-
1.2%, szone_free, libSystem.B.dylib
1.2%, get_user_regs, mach_kernel
-
1.1%, szone_free_definite_size, libSystem.B.dylib
-
1.0%, copyin_kern, mach_kernel
-
1.0%, CFBasicHashApply, CoreFoundation
-
1.0%, __nanotime, libSystem.B.dylib
(Tree View)
Generated from the visible portion of the outline view- 53.8%, start, lptTPC
| + 53.8%, _start, lptTPC
| | + 53.8%, main, lptTPC
| | | + 53.8%, QEventLoop::exec(), libqt-mt.3.3.8.dylib
| | | | + 53.7%, QEventLoop::enterLoop(), libqt-mt.3.3.8.dylib
| | | | | + 53.5%, QEventLoop::processEvents(unsigned int), libqt-mt.3.3.8.dylib
| | | | | | + 44.0%, ReceiveNextEvent, HIToolbox
| | | | | | | - 43.5%, ReceiveNextEventCommon, HIToolbox
| | | | | | | 0.1%, GetMainEventQueue, HIToolbox
| | | | | | | 0.1%, AcquireEventFromQueue, HIToolbox
| | | | | | | 0.1%, GetCurrentEventQueue, HIToolbox
| | | | | | | 0.0%, ShouldTurnOffMMXMode, HIToolbox
| | | | | | | 0.0%, GetCurrentEventTime, HIToolbox
| | | | | | | 0.0%, RunCurrentEventLoopInMode, HIToolbox
| | | | | | - 6.1%, QApplication::sendPostedEvents(), libqt-mt.3.3.8.dylib
- 37.8%, get_user_regs, mach_kernel
| - 33.0%, mach_msg_overwrite_trap, mach_kernel
| - 1.4%, inval_copy_windows, mach_kernel
| - 1.0%, mach_kauth_cred_uthread_update, mach_kernel
Ultimately it calls QtSingleApplication::exec() to kick off the event loop. This is where the program sits in steady state, so I assume the problem exists here.
It seems like the event loop's operating behavior is that of busy-waiting.
I've tried google searching for this, but almost all of the hits are for Apple developed programs that are pegging the CPU.
Would someone please help me figure out why the CPU usage is so high and how to fix it?
I posted this over on the Apple Developer forums and here is some of what I was told:
bq. It is polling for updates instead of waiting for them. This is common behaviour in cross-platform toolkits like this. The solution was released in 1983 with the select() function.
Thanks in advance.
- sib3
-
1/1