I am creating a mechanism for sending and receiving data on multiple servers. Servers are run on Windows and Delphi 7 is used.
Sending data is formed in several simultaneous threads and it is not possible to know which thread will form the data first. The moment of adding data to the buffer is synchronized by CriticalSection. The sending threads are constantly checking if there is any new data for sending. By doing this each thread eats 1 CPU core. This works very fast, but CPU is about 100% even when the server is not sending data. I need more than several threads and I need to avoid this high CPU usage.
I have tried two options:
Sleep - If there is no data in the buffer I run sleep(1). The CPU core is not loaded, but the speed of reacting to new data is about 100 times less. This is not a solution.
Killing and creating threads. If there is no data in the buffer I kill the thread. The function that adds data will create a new thread. The new thread will send the data, free up the buffer and will be killed again. The CPU load is decreased but creating and killing takes too much time. As a result the speed is 100 times lower.
Is there any alternative to sleep(1) that is not consuming 100% CPU and reacts rapidly? Or is it possible to pause threads before some event occurs?
The question is answered. This works for me https://stackoverflow.com/a/4401519/4052208 .
The best solution to limiting the cpu usage for a process or thread is to make sure that the thread or process uses less cpu. That can best be done by improving the efficiency of the code, or by calling it less often. The aim is to make sure that the process doesn't continually consume all of its available time slice.
Although you can take advantage of multithreading to perform several tasks simultaneously and increase the application's throughput, it should be used judiciously. Incorrect usage of multithreading may result in high CPU usages or increased CPU cycles and can drastically reduce your application's performance.
Multiple instances of a service running on one server or in a multi-core environment can produce CPU usage percentages well above 100%. If you upgrade from a dual processor to a quad processor under the same architecture, you should see roughly the same CPU numbers for the same loads and applications.
Multithreading adds stability to the programs and prevent it from crashing. All threads run independently. So if an error is encountered by a thread, it should not affect rest of the program. It allows better utilization of the processor and other system resources (Blumofe et al., 1996).
You might let threads to wait for data with WaitFor*
functions. They won't eat processor resources.
I'd recommend to use WaitForMultipleOjects
, which has possibility to wait for some events. For example, main event (look for CreateEvent
or Delphi wrapper class TEvent
) should be set by data producer when data is in buffer, and another event serves for thread termination:
//Execute body
repeat
WaitRes := WaitForMultipleObjects(2, @FEventHandles, False, CONST_TIMEOUT); // or INFINITE
if WaitRes = WAIT_OBJECT_0 + 1 then // event from data producer
GetDataFromBuffer();
until WaitRes = WAIT_OBJECT_0; // external event for thread stop
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With