duckduckgo
duckduckgo

Reputation: 1295

Limiting number of threads run from timer

I am having a WM_TIMER callback function fired after every 50 millisecond, inside this I create a thread just to ensure ui thread is not blocking, these thread operate on a shared memory which I made thread safe using mutex object.

My problem is when new threads are created and earlier threads not yet finished they goto waiting state after hitting the line WaitForSingleObject(ghMutex, INFINITE) because of this number of active threads in memory will be rise exponentially, probably I should do this without timer, but I think with timers I can better manage frequency.

I also tried to use a thread counter (tells number of active threads) and return from callback function if counter is greater than zero, as per my understanding this is not thread safe.

What should I do to keep only one thread running anytime, for example if a thread fail to acquire mutex lock then it should terminate instead of waiting.

Upvotes: 0

Views: 239

Answers (2)

Jerry Coffin
Jerry Coffin

Reputation: 490128

It seems to me that you're violating one of the most basic principles of threading (and although @Dim's answer is an improvement, it's still doing the same). One of the biggest points to keep in mind is that threads should run as independently as possible. Ideally, you want to minimize synchronization and communication between threads to the minimum necessary for them to do their jobs.

In this case, the minimum seems to be "none". The main thread has to create the worker thread. After that, none of what you've described requires any further communication at all.

At least as I understand it, the intent here is that the worker thread do some sort of processing at 50 ms intervals. Assuming that's correct, you seem to gain precisely nothing from having the UI thread involved at all. Instead, you should have one (and only one) worker thread that start up, and in a loop does something like:

  1. Record the current time
  2. Do its processing
  3. sleep for the remainder of 50 ms since starting (if necessary)
  4. Repeat

Although you haven't described anything about it, the only place here that I see a (probable) need for inter-thread communication is for this worker thread to tell the UI thread that a round of processing is done, and the UI can use the data to update the UI. I don't know what form that takes in your case (and it may not be necessary at all) but I can at least see where it might be needed. Simply getting the thread to do something every 50 ms, however, is not sufficient justification for doing any sort of inter-thread communication (not to mention the overhead of creating a new thread every 50 ms, then adding still more overhead to ensure that you only have one worker thread at a time).

Upvotes: 2

dim
dim

Reputation: 660

Here is what you can do, based on your description and the addtional comments:

Have:

  • One thread for the GUI (that receives timer events)
  • Another thread for the processing.
  • An event (created with CreateEvent)

The processing thread will have a big infinite for(;;) loop that starts by waiting for the event, then do the processing required. The timer event, instead of firing a new thread each 50ms, would just call SetEvent to trigger the processing thread.

This way, you can't have more than one "processor" at the same time. If it takes longer than 50ms to proceed, it is discarded.

If each event needs more than 50ms to proceed, you can have more than one processing thread+event, and you trigger them alternatively from the timer in a round-robin fashion (cycle trough them).

Upvotes: 2

Related Questions