6

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:

  1. 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.

  2. 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 .

Community
  • 1
  • 1
  • 1
    See this: http://stackoverflow.com/questions/4401171/self-suspending-a-thread-in-delphi-when-its-not-needed-and-safely-resuming – Ville Krumlinde May 05 '16 at 10:25
  • 2
    Have you tried using OmniThreadLibrary - http://otl.17slon.com/ ? – RBA May 05 '16 at 11:50
  • 5
    Don't have your threads check - notify them when work is added. Threads can wait on synchronization objects like `TEvent` - when work is added to the queue you can grab an available thread and signal it to begin work. Libraries like OTL implement this type of thing if you don't need anything special enough to re-invent the wheel. – J... May 05 '16 at 11:55
  • @VilleKrumlinde Thank you. First answer from here worked for me http://stackoverflow.com/a/4401519/4052208 – Andriy Popov May 08 '16 at 13:42

1 Answers1

9

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
MBo
  • 77,366
  • 5
  • 53
  • 86