0
\$\begingroup\$

In my TCP multithreaded server written in C, I have multiple threads with infinite loops checking for new inputs from thread safe queue and then doing their jobs. pseudocode:

void jobThread(void * arg){
    CustomQueue queue = (CustomQueue) arg;
    while(1){
        if(customQueueNotEmpty(queue)){
            doSomeJob(getItemFromQueue(queue))
        }
    }
}

I have multiple threads running like this, but number of threads is directly controlled with program. It is not like threads are spawned for each user online or job to be done, but rather user sessions and game-jobs are added dynamically to prespawned threads. Most probably the number of threads will be limited by number of CPUs on host machine.

My question is about the while(1) statement. In case when there are many users connected and many jobs to be done this is probably fine, because all of the CPU time is just used to do the job. But otherwise, most of the CPU time gets burned just to loop and check queue.

Should I add sleep() to make thread less CPU exhaustive? Or should I not use while(1) since it is not a good practice? Or do I not care at all since every thread can get its own CPU core and therefore does not slow other threads?

Edit: Philiph's answer suggested using condition variables which I imagine using something like this:

void jobThread(void * arg){
    CustomQueue queue = (CustomQueue) arg;
    while(1){
        while(customQueueNotEmpty(queue)){
            doSomeJob(getItemFromQueue(queue))
        }
        pthread_cond_wait(cond); //when queue is empty wait for other thread to reawake this
    }
}

and then in other thread that fills the queue call:

putInQueue(quueue, item);
pthread_cond_signal(cond);

when new message arrives. But what about case, when consumer thread reads queue as being empty just before the moment of producer thread filling it with new message. Then the consumer thread would wait without processing the new message and only awakening after yet another message arrives to awake the consumer and make it process both new messages.

\$\endgroup\$
2
\$\begingroup\$

Having a thread busy-spin like that is not a good idea. It causes unnecessary CPU load. This drains the battery of mobile users device, causes unnecessary heat and power consumption for desktops and servers and steals CPU time from background processes.

A better idea could be to make the thread pause itself when it completed processing its message queue. Then have the system which handles the message queue resume the thread as soon as it enqueues a new message. How to do that depends on what threading library you are using. I haven't got any experience with multithreading in C in particular, but a cursory research tells me that pthread is a popular library choice, which further points me to pthread_cond_wait and to this stackoverflow question.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for your answer. But what about situation when thread that enqueues messages adds new message just after the consumer thread went sleep? I edited my question to explain this more deeply. \$\endgroup\$
    – user154155
    Jul 3 at 12:11
  • 2
    \$\begingroup\$ @user154155 sounds like you might want to read up on how to safely implement a single producer multiple consumer queue — StackOverflow has lots of Q&A about this. \$\endgroup\$
    – DMGregory
    Jul 3 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.