ScarCode
ScarCode

Reputation: 3094

A Simple pthread_create causing 100% CPU usage in Qt

When a simple Thread is run with just an infinite loop in it causing 100% CPU, how come is this possible?

My thread call is as follows on a QEvent in Qt dialog class, Say on a button click.

  pthread_t thread_id;
  pthread_create( &thread_id, NULL, DataCollectionThread, (void*) this );

And my thread procedure is,

void* DataCollectionThread( void* pParam )
{
   ((m_DataCollection*)pParam)->m_ReadDatafromport();
   return NULL;
}

And this ReadData() contains...

while(1)
{
}

My requirement is collecting data from serial port and plot a graph continuously. But as the CPU usage is 100%, any hardware interrupt in between plotting cause the plotting to stall, as the CPU switches the task to handle interrupt.

I am calling this thread in a Qt::Dialog based class. I am pretty sure that nothing other than this is triggered. What's wrong with this? Does a simple infinite loop causes 100% CPU consumption eh? Or Is there any problem with using pthread_create in Qt?

EDIT:For Jonathon Reinhart

This is the actual while loop

while( 1 )
    {

            while(( Dataisavailable))
            {
                 //push the read data to stack
            }



        if(!m_DataReadable)
            break;
      }

Upvotes: 1

Views: 3960

Answers (3)

Unlike cooperative multitasking, true OS-supported threads allow the CPU to interrupt code that's locked like this. So your computer isn't completely dying. But some degradation will occur. The computer doesn't have a good way of knowing not to try its best to run the code it's given if there is work to do...short of scheduling tools like nice

Sometimes you can mitigate the problems caused by something like this with "thread priorities". Qt has a QThread::setPriority() abstraction but note that it says:

The effect of the priority parameter is dependent on the operating system's scheduling policy. In particular, the priority will be ignored on systems that do not support thread priorities (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler for more details).

Seems the Qt people looked at thread priorities under linux and gave up. So if that's your platform, then you likely should just design your system so it doesn't spin like this.

I'd be curious what happened if you change ReadData() to...

QMutex dummy;
while(1)
{
    QMutexLocker locker (&dummy);
}

(which was my way of trying something that may be more effectively done with the sched_yield that @jweyrich just mentioned.)

Upvotes: 2

Managu
Managu

Reputation: 9039

One simple hack to get around this: Go to sleep for (short) periods to let the CPU do other stuff. #include <ctime> and add somewhere in your loop:

struct timespec ts;
ts.tv_sec=0;
ts.tv_nsec=10000000; // 10 milliseconds
nanosleep(&ts, NULL);

Of course, it would be better if you could explicitly sleep until you have actual work to do (more input to read, a full queue to trim). But adding in short sleeps will probably be sufficient.

It might make sense to look into your m_pDataProvider object's implementation. Check for or add a method allowing you to sleep until there's more data. If you're just reading from a character device (e.g. ttyS0), poll or select might be useful here.

Upvotes: 1

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137497

YES.

while(1) { }

Is going to do the following:

1. Does the number 1 equate to true?
2. Yes.
3. Go to 1.

The CPU is going to continuously do this whenever that thread is executing. Why are you starting a thread just to put it in a spin loop that does nothing?

Upvotes: 1

Related Questions