简体   繁体   中英

Why does Thread.Sleep( ... ) avoids CPU using 100% of a heavy execution from a multithread windows service based application?

I have a huge text parsing windows service application that takes usually 20 minutes to finish the whole process, and it consumes 100% cpu. I set a Thread.Sleep(500) at the end of each item in the loop and now the cpu consumption is between 70% and 0%.!!! and it takes about 3 hours to finish which is fine for my business case.

The question that might be obvious for some but not for me, why did the delay make it consume less CPU?

When looking at the CPU usage in task manager what you're actually looking at is the percentage of non-noop commands over a given interval of time. A given core of a CPU can't be 34% on. Either it's doing something, or it's not, but it can switch back and forth literally billions of times per second. By inserting Sleep commands the result is that the CPU is spending a lot more time doing nothing, even though it has work that it could be doing. When the time spent nothing is averaged together with the time spent doing something the result is less than 100% usage. If you slept for longer periods of time, but did so less often, you'd see it jumping between 0 and 100% (which is what's really happening, you just can't visualize it currently).

If you drive around all day, the car will be at 100% use. If you sleep after doing the groceries and before driving to work and then sleep again after getting home from work and before going to the club, the car's usage will be less than 100%. When your code is sleeping, it's not working.

I should point out that when there's useful work that needs to be done, you should want your CPU to be at 100%. There doesn't seem to be any good reason to slow down the rate at which work gets done. If the issue is that your system is slow, that probably means it's doing the wrong work, not that it should be doing less work.

Because sleep means it's not actually working - thus virtually no CPU time used. It will make the program take longer, but you won't be sitting on the CPU.

It averages out. In reality your processor will be repeating this loop until it's done parsing your file:

  • 100% CPU load reading stuff
  • 0% CPU load, sleeping for 500ms

Repeat that over and over quickly, and you process monitor will average this out to 70%.

Assume that you need to count up to 1,000,000. You start numbering very fast and complete the task in 1 day. What if you stop 10 seconds when you reach each thousand? You will:

  1. finish much later

  2. however, you have 10 seconds of "sleep"; in this interval you can think of something else (or nothing :) ) besides counting so your task will not consume 100% of your attention.

Btw, you question sounds more like a logical one rather than a programming one...

Thread.sleep does not cause CPU usage. In a multithreaded environment, doing long Thread.sleep causes system to spawn more threads for usage rather than reusing the already created ones. That process is extremely costly and hence the High cpu usage. Thats what is happening in you case. You can confirm by creating a while loops and creating new Threads and making them in turn create a thread in sleep.cpu usage will hit 100 %

Reading the above I can understand the Thread.Sleep does not consume CPU time, I do something similar with a incoming ASP.net application where the incoming request creates a Hangfire job which is executed and performed in another thread, while waiting for that intensive job to finish and so I can return the response in the same request, perform Thread.Sleep on the worker process while waiting. In this case I find the connection pool is still holding a open worker thread while the thread is sleeping, but as said above the CPU isn't consumed while doing so and when the background Hangfire Job finished update a reply to the worker process and release and return the data as it's done.

I've read a asynchronous task is also a approach to this, but, since I separate the worker process using Hangfire, the work done isn't in the same thread, so sleeping the worker process doesn't impact the worker process request being handled.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM