Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


Problem with thread synchronization and multithread processing.

Posted on 1998-07-13
Medium Priority
Last Modified: 2010-04-10
First a little background:
I am currently working on a program that waits for data from users via the internet.Currently , it immedialtely processes the information using a thread. I am adding a feature that allows the user to process the information at a time delay instead of immediatey. To do this I created a thread that simply sleeps for the length of the time delay, afterwhich the ProcessData thread is started. I used a critical section as a means of synchronizing the threads (this was necessary because if they were not synchronized I got a C++ runtime error).

The problem that I am having now is that the process waits to deal with the data that is being sent by the user until after the delay from a previous user has been completed. I am currently using WaitForMultipleObjects which  is leading to the problem. Using WaitForSingleObject(DelayThread,INFINITE) and this leads to the same  problem. If I don't have a wait at all I get a C++ runtime error.

Here is my question:
How can I have the program process infromation from one source at a delay and still have it process information from another source that is not at a delay WITHOUT the second set of information having to wait until after the delay thread has been completed for the first set of infromation?

I hope this makes sense.
Question by:delicia071398
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 22

Expert Comment

ID: 1167653
>> How can I have the program process infromation from one source at a
>> delay and still have it process information from another source that is
>> not at a delay WITHOUT the second set of information having to
>> wait until after the delay thread has been completed for the first set of
>> infromation?

It is not clear why this problem is occuring.  Why do you think you have to wait?  

Is it that the sleeping (waiting) thread is supposed to handle both sets of data, and is sleeping for one so it doesn't "see" the one that it doesn't need to sleep for?

Is it that there is one set of data (not two) and both forms of processing must occur in the one set?

Or is there something else?


Author Comment

ID: 1167654
If I do not have a WaitForXXXObject(s) I get a C++ runtime error that I have traced back to the call to DelayThread.Which at that time would sleep for the delay time and then call another function the started the ProcessDataThread.

I then redesigned the program so that the the first thread (Thread1) would sleep (and that is it) without calling the function that starts ProcessDataThread(Thread2).Thread2 is supposed to handle both sets of data but Thread1 is not. I use a series of if statements that determine whether or not the data is to be delayed if it is not the _beginthread(Thread1) is bypassed.

As a  sidebar the design for the program is such that each piece if data submited by the user is to be delayed (if necessary) otherwise be processed immediately.There are at any given time any number of users that can be sending data to the program via an application extention (dll) that receives information from the internet.This data may/may not have a time delay. The time delay from one set of data sent to the prgram from the Dll should not affect the processing of another set of data that is sent to the program from that same Dll. The program is designed to run "infinitely" and continually waits for messages from the internet.

Expert Comment

ID: 1167655
The design you describe requires a separate thread for each pice of data which requires a delay. The basic plan would be:

- thread1 is in a loop looking for messages

- if a message comes in which is to be processed immediately, thread1 processes it

- if a message comes in which needs to be delayed, thread1 creates a new thread threadN (where N gets larger as there are simultaneous requests which need delays)

- each threadN sleeps the required time, then wakes up and processes the data itself (without calling thread1). When done, each threadN terminates itself.

The reason this is necessary is if the basic delay mechanism is for a thread to sleep, then either each new piece of data needs its own thread or else it has to wait for the previous delay to be complete so the shared thread is again available. There's no other way.

Having said all that, that's the easiest way to modify your present design to make it work, but it's probably not how I'd do it. Creating a new thread all the time has significant overhead, and you have to be careful to lock common resources with Critical Sections. (One critical section protecting all your data processing sounds feasible, though, since all threads do the same thing).

The other way to do it, and to remain a single-threaded app with all the simplicity that brings, is to maintain your own list of pieces of data awaiting processing. This scenario would work as follows:

- thread is in a loop looking for messages

- if a message comes in which is to be processed immediately, thread processes it

- if a message comes in which needs to be delayed, thread adds it to an array of pending messages along with the current time (obtained from GetTickCount).

- before going back into its message loop, thread always looks into the array to see if any entries are ready to run. This is done by calling GetTickCount to get the current time and seeing which if any of the array entries' time delays have passed. Those who are ready are processed and removed from the array.

- If there are entries in the array, before we go back looking for new messages we need to start a timer, with the time set to the delay for the next array entry which should run. Only one timer is ever used, though - if we already started the timer but haven't received notification yet then no need to do anything here. The timer doesn't actually directly time the delays, it is there to wake up the thread so it can check its array.

Let me know if you need clarification... if what I said helps I'll repost it as an answer. Good luck!

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.


Expert Comment

ID: 1167656
Hello Delicia!
I suggest that you establish two queues for the information processing. One queue would be the delay queue, the other would be the immediate queue.
Data entered into the delay queue is associated with a time stamp.
Both queues should be monitored for explosion prevention (for example, requests are not admitted for length of queue exceeding 20).
The thread polls both queues. If the immediate queue is non empty, all requests need to be processed.
The Delay queue is monitored, and using the time stamp, requests are served "when ripe".
Note, that this mechanism also allows you to balance both queues with the introduction of queue balancing policy: For example, no more than x immediate requests are served before the delay queue is polled; Delayed requests that have not been served when due may be entered in front of the immediate queue.
Good luck, Roni

Author Comment

ID: 1167657

Your answer to the question was great. I used the array to store the messages and that alleviated the problem without having to deal with the overhead of continually creating new threads.

I need clarification on the use of GetTick Count though I have never used it before. Am I correct in saying that the count is represented in milliseconds? and is returned as a DWORD? Also how would I know which message is to be sent next . Would I have to loop through the array to find the next message to go that i snot one of the messages whose delay has expired?

Accepted Solution

alamo earned 400 total points
ID: 1167658
Glad it helped you!

GetTickCount() is my preference for a quick easy timestamp... yes it's milliseconds since Windows was booted, returned in a DWORD. It's not a good timestamp if you need precision in your delays, the value is in milliseconds but is only updates every 10ms or so, and sometimes falls behind if the system is busy.

DWORD dwNow = GetTickCount();
if (dwNow - timestamp) >= delaytime) etc.

[Note that you shouldn't say if (dwNow <= timestamp+delaytime) because the DWORD overflows every 50 days or so and the comparison will fail... the one I gave you will still work.]

As to which message to send next... if all messages have the same delay, you can just look at the end of the array where the oldest message is and check its timestamp (it's functioning as a queue). If however different message have different delays, you will have to check each entry in the array to find which entries' delay has expired and thus are ready to be processed.

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question