views:

1588

answers:

3

Hi.

There are several threads in my application that work in the background. They connect to database and execute some time consuming select queries. In most of cases these queries return only several records. From time to time, however, they may return tens of thousands records. All these are then processed in a loop.

Because such situation may occur in several threads at the same time, I do not want my application to use 100% of CPU time when those threads are processing data; neither do I want to make all threads fight for processor's time. Therefore I call the Sleep() function in each iteration of the loops in those threads.

I do not know, however, how to adjust the sleep time. I do not want the loops to last forever, so the sleep period can not be too long. I set it to 2 milliseconds in each iteration (in each thread) (why 2ms? - that's a good question :) ).

I thought, on the other hand, that I could prolong the sleep time, but call sleep only once every n iterations (let's say, Sleep(100) every 50 iterations). Which approach should I choose? One itertion of the loops takes about 30 ms each (without any sleeps).

Please advise.

Thanks!
Mariusz.

+2  A: 

There may be better approaches than using sleep to control your threads. Since your database call can return 1-1000s of records for processing, it might make sense to separate your application into two layers, maybe using a message queue to buffer the requests. Your app could call off to a data service, and the data service would then run the query and dispatch individual data messages (or blocks of messages, etc.) to a queue. Your app can then create as many threads as appropriate to process messages. More threads means faster processing at the expense of CPU, but you can adjust this to get the right balance.

Andy White
+6  A: 

Calling Sleep() makes no sense. Use all the processing power you can get, and let the system work out how to best schedule your threads. Calling Sleep() will only cause extra context switches and lower your throughput. If background processing interferes with your main thread or other applications, then lower the priority of background threads accordingly.

If you want to let threads sleep to limit the amount of data they generate for consumers, look into producer-consumer-queues. Have the producer threads simply block when their queue is full, this way you will not need at all to fiddle with the timing.

Note also that using maximum CPU is generally a good thing, especially on modern processors. Even on laptops having a short time of high load is better than artificially prolonging the time your task needs, as the processor / whole system will sooner be able to enter lower power states.

mghie
But if this runs in the background on a computer that also has somebody working on (e.g. writing a spreadsheet), you don't want the background process to make the foreground process unusable.
dummzeuch
True, but that's why I wrote that background thread priority can be lowered, keeping other apps (or the main thread) responsive while still using the full system potential. On modern (multi-core) systems keeping all cores sufficiently loaded is much more of a problem than lack of responsiveness of the foreground application. And massive non-optimized I/O is a much bigger threat to the usability of a system than high CPU load, anyway.
mghie
+2  A: 

You better just make low priority threads and let them work without sleeps, otherwise you do not use the full power of the CPU. For example on multi-core/multi-cpu systems. Or if your system is 100% idle: why wait or sleep?

But if you need some sleeps however, note that sleep(1) waits 10-15ms (!) because of the default Windows timeslice. You can use timeBeginPeriod(1) of the MMSystem.pas unit to set the resolution to 1ms :-) (I used this for serial communication).

André