views:

64

answers:

4

Hi all,

I've created two threads A & B using CreateThread windows API. I'm trying to send the data from thread A to B.

I know I can use Event object and wait for the Event object in another using "WaitForSingleObject" method. What this event does all is just signal the thread. That's it! But how I can send a data. Also I don't want thread B to wait till thread A signals. It has it own job to do. I can't make it wait.

I can't find a Windows function that will allow me to send data to / from the worker thread and main thread referencing the worker thread either by thread ID or by the returned HANDLE. I do not want to introduce the MFC dependency in my project and would like to hear any suggestions as to how others would or have done in this situation. Thanks in advance for any help!

+1  A: 

Since the two threads are in the same process (at least that's what it sounds like), then it is not necessary to "send" data. They can share it (e.g., a simple global variable). You do need to synchronize access to it via either an event, semaphore, mutex, etc.

Depending on what you are doing, it can be very simple.

Thread1Func() {
  Set some global data
  Signal semaphore to indicate it is available
}

Thread2Func() {
  WaitForSingleObject to check/wait if data is available
  use the data
}
Mark Wilkins
Correct! Let's say Thread A updates the global variable. How does it intimates Thread B?
AKN
Thread B waits in the call WaitForSingleObject till Thread A signals. Is there any way by which I can make Thread B to continue its job instead of waiting for Thread A to signal?
AKN
@AKN: don't do it. Globals are problematic when you have only one thread -- multithreading will multiply the problem. Just don't do it.
Jerry Coffin
@AKN, thread B can have its own copy of the variable. When the job is done, it can check if the global variable has changed, copy the value and start doing work again, or sleep or wait for a signal.
Nick D
@AKN, The WaitForSingleObject API accepts a timeout value. You can specify a 0 timeout and determine from the return value if it the semaphore was signaled or not. That way it won't wait and can continue working.
Mark Wilkins
@Mark: Fair enough. But is there any solution other than WaitForSingleObject?
AKN
@AKN, It's not completely clear to me what you are looking for. There are other synchronization objects (e.g., mutexes, events, critical sections). Using a message queue as Jerry Coffin wrote about is another option. It really depends on your architecture and what you are trying to accomplish for what works best. In fact, if your goal is to be process and machine independent, you could even use sockets to send data. I disagree with Jerry's "never use globals" comment, but I do think a "be very careful" statement certainly applies.
Mark Wilkins
Ok. Let me try out the listed options!
AKN
+3  A: 

First of all, you should keep in mind that Windows provides a number of mechanisms to deal with threading for you: I/O Completion Ports, old thread pools and new thread pools. Depending on what you're doing any of them might be useful for your purposes.

As to "sending" data from one thread to another, you have a couple of choices. Windows message queues are thread-safe, and a a thread (even if it doesn't have a window) can have a message queue, which you can post messages to using PostThreadMessage.

I've also posted code for a thread-safe queue in another answer.

As far as having the thread continue executing, but take note when a change has happened, the typical method is to have it call WaitForSingleObject with a timeout value of 0, then check the return value -- if it's WAIT_OBJECT_0, the Event (or whatever) has been set, so it needs to take note of the change. If it's WAIT_TIMEOUT, there's been no change, and it can continue executing. Either way, WaitForSingleObject returns immediately.

Jerry Coffin
A: 

If you are concerned with minimizing Windows dependencies, and assuming you are coding in C++, then I recommend using Boost.Threads, which is a pretty nice, Posix-like C++ threading interface. This will give you easy portability between Windows and Linux.

If you go this route, then use a mutex to protect any data shared across threads, and a condition variable (combined with the mutex) to signal one thread from the other.

A: 

Don´t use a mutexes when only working in one single process, beacuse it has more overhead (since it is a system-wide defined object)... Place a critical section around Your data and try to enter it (as Jerry Coffin did in his code around for the thread safe queue).

Incubbus