views:

1067

answers:

5

Hello,

I have a general Question about inter-thread communication.

Right now I am using a bunch of C++ thread (~15).

They are all using BusyWait(Polling) each others to get data to process. But it is hard to keep cpu usage low && give good performance and avoiding doing too many context switch.

So I am looking at Condition variable, and signal. I think I understand the general concept of having on thread going into .Wait(), waiting for another thread calling .Signal().

Question #1) My problem might be conceptual, but if the thread waiting for a signal get SUSPENDED while waiting, it is not able to perform any action, by its own. Is there anyway to let it wake up by itself to perform some actions.

Question #2) In addition my class are use to pass data in both directions. But if the middle class is waiting for signal from another class, it is unable to send signal to that class. Such as:

 _________                       _________                       __________
| Class A |---newData Signal--->| Class B |---newData Signal--->| Class C  |
|         |                     |(WAITING)|<---newData Signal---|          |
 ---------                       ---------                       ----------

So if Class B is on .Wait() for .Signal() from C, it is unable to process the new signal from A.

Is it possible that both A && C send the same "newData" signal B to wake it up? Would it be possible to differenciate the signal from A && C.

I am coding this using C++ using ACE framework & might switch to Boost. But I guess this is generic enough that I could apply the answer to any OS (hopefully).

Thanks

+2  A: 

If you want your parent thread to do work while a child thread is running, you can wait for a signal with a timeout. Every time the timeout expires you do some work and wait again.

Otávio Décio
+1  A: 

Question #1) On most implementations you can limit the maximum wait time and so say: wait for 2 seconds, then do something and wait again.

Question #2) On most implementations you can wait for more than one signal at once. You can say: wake up if signal A or B is triggered.

rstevens
Can you give example of function waiting for more than on signal? I have looked at Boost and haven't seen any such thing. On Windows only side there seem to be WaitForMultipleObject, but I am not sure if that's what you are talking about... Not sure about Linux...
@xcimo: Yes, WaitForMultipleObject is what I mentioned for Windows. Unfortunately I don't know what boost can give you (we use a hand written cross-platform class which internally uses WaitForMultipleObject for Windows and complex code around pthread condition variables on Linux).
rstevens
A: 

The answers that you seek are very complex and the space on this wiki isn't really big enough to address them all :(

What you need to do is to find yourself some good web sites that offer explanations of how threading works. Most of what you are after can be done with the correct designs, but you need a much better understanding of the concepts first.

In order to get your communications to work out you need to send signals to the right places and wait on the correct events.

The simplest way to do this which will get you something that works better than polling is to use a single condition variable that all of your threads share. When this condition is signalled they will all wake up and look for some work to do.

This is not efficient, but is simple and will work for you and is more efficient than the polling. Once you have this working you can try to introduce some new condition variables and split which threads wait on which ones -- when doing this you will make many mistakes and experience many deadlocks and starvations. Persevere and you will start to understand how this all works.

Good luck.

KayEss
A: 

Although you can use condition variables for this, the problem description suggests the use of a message queue instead. Then, thread A and thread C can inject messages into B's queue, and B processes them accordingly. (Of course, to differentiate between the two threads, you should arrange for A and C to send different messages.)

I don't know what support for message queues ACE has, however, in (say) the Java concurrency framework, you can build your own poor-man's message queue using ConcurrentLinkedQueue. :-)

Chris Jester-Young
All my thread/class already have Queue, in ACE they are call ACE_Unbounded_Queue. So this is not an Issue.
A: 

Assuming you have some way to do critical section locking (e.g. java synchronized) or a thread safe queue, you could use a run queue.

For each thread, modify/override the sleep implementation so that when the thread waits, it adds itself to the end of the run-queue.

Assuming that only one thread should be running at a time the last thing the currently running thread should do before it itself goes to sleep/waits is wake the thread on the head of the list.

If you need more complex execution/scheduling of the threads, the next step is to create a scheduler thread that walks the queue, adjusting the order of threads in the queue, checking to see which thread has all the resources it needs to run, etc.

Jato