progschj / ThreadPool

A simple C++11 Thread Pool implementation
zlib License
7.64k stars 2.21k forks source link

100% CPU utilization #32

Closed atari83 closed 8 years ago

atari83 commented 8 years ago

Hello there,

At first, I'd like to thank you for your great work. I just imported the code in my project and it just working fine. :)

However, one thing that bothers me is that as soon I create the thread pool (and ofcourse adding some initial tasks in there), the CPU usage is getting increases over the time and eventually reach 100% (after 10sec), with considering the fact that there is no remaining tasks in queue.

Is it normal behavior ? or am I doing something wrong ? and If you have suggestion for me.

btw, my build environment is FreeBSD 10.2 amd64 RELEASE

Thank you,

atari83 commented 8 years ago

any comment on this ?

atari83 commented 8 years ago

Well, it was a little awkward, but as soon as I add a sleep (1ms) in my worker thread loop, I dont face high cpu utilization problem anymore ..

progschj commented 8 years ago

I haven't observed that behavior before. Is the Threadpool just being present enough?

Darelbi commented 8 years ago

If not implemented properly a lockless (It don't look lockless) thread pool will have 100% cpu utilization because of workless threads racing against catching some work, sleeping will just add a undetermined delay wich may make un-responsive the pool in performance critical applications (wich would be the reason to use a lock-less pool, otherwise just use a standard Thread-Pool).

A slightly better way is to sleep only if no work is found (until there's work, no time is wasted sleeping).

The definitive correct way would be to manually put the thread to sleep when it has no work and awake it using correct primitives (or basically use a Monitor synchronization primitive). This has high chance to sleep much less than a "sleep(1)" and to not sleep if there's work to be done.

EDIT: It don't seems a problem of the pool it works nice here

Darelbi commented 8 years ago

Can you post a snippet that reproduce the problem? right know I'm not able to reproduce it.

atari83 commented 8 years ago

Darelbi, Thank you for response ... I guess you're right :) It's all about a work-less thread ... but still I'm confused that how can I change my application logic to actually let the thread sleeps when there is no work available. Maybe that's because the application doesn't know that!

you see .. in the thread , I've to constantly check an API to make sure if there is a job for me:

while (1) { // sleep for 1ms , has solved the issue bool b = call_api (....); }

I'm not sure how can i change this logic, to actually cover my both targets: 1- finding out if there is a job , 2- letting same thread sleep when there is no job !

Thanks again

Darelbi commented 8 years ago

if you have to poll an API and there's no awake callback in the API itself (or better the API lock a mutex when creating work for you), then sleep is your best bet. (also tried with sleep(0)? I think there's also a "yield" call that will just get the thread descheduled), I guess the API is not looking for input/outpute otherwise input and output will just make the CPU idle while waiting for input. (if a thread wait for input like a socket it will use almost no CPU at all)

In NodeJS there's 1 thread looping to seek for input/job, and then work is delegated to worker threads. If 1 thread is enough for you (provided you are input bound) then you can get 50% utilization for a dual core, and 25% for a quad-core etc, using the same approach.

atari83 commented 8 years ago

Thank you Darelbi, I'll try with sleep(0) and share the result here