views:

777

answers:

4

Environment: Win32, C/C++

All three (3) can be used for a thread to signal to main() that it has completed an operation for example.

But which one is the fastest signal of all?

hmm...

A: 

Have not checked but (assuming you have someone waiting for the object) I would say SetEvent, SendMessage and finally PostMessage.

Edit: The reasoning behind the above is simply that SendMessage is synchronous and PostMessage is asynchronous. I am not sure about the SetEvent but I would assume it to trigger something waiting for the event without having to wait for the message pump delivering the message. Thinking about it sending or posting probably doesn't matter, it is just a matter of if the sending party will wait or not. The internal processing is probably identical.

However, neither posting nor sending a message is normally what you would use to send a signal to another thread.

Fredrik
+2  A: 

SetEvent is by far the fastest and the simplest but it also can carry the least information. Basically all it can say is that something happened (the event was signaled) nothing more.

Stephen Martin
+5  A: 

All three options require a thread context switch to actually signal the receiving thread. It's quite likely that the overhead of the context switch will overwhelm any difference in processing cost in any of the APIs.

The choice is likely best driven by the nature of the receiving thread, e.g. is it a UI thread, and/or does it carry out a message loop. That said, some fine detail includes:

  • SendMessage is useful when the receiving thread is a UI thread, churning inside a message loop. The sending thread will block until the recipient processes the message. But it may handle unqueued messages during that time. That logic could potentially slow things down, as additional context switches may be involved, making SendMessage the slowest of the three.

  • PostMessage is also useful when the recipient is inside a message loop. The difference from SendMessage is that it doesn't wait for the recipient to process the message, thus incurring less overhead.

  • SetEvent is useful when the receiving thread can wait on an event object, e.g. with WaitForSingleObject(). It incurs no marshaling or message processing overhead, and is likely to respond quicker than the others.

Oren Trutner
A: 

If you look at MsgWaitForMultipleObjects vs WaitForMultipleObjects, you will see that the maximum wait objects for MsgWaitForMultipleObjects is one less than WaitForMultipleObjects meaning that there is a hidden "on message event" so a message will have the overhead of a event + the message passing

Anders
That's an interesting observation, but it doesn't necessarily mean that messages are implemented on top of events or have more overhead than events. `WaitForMultipleObjects()` can wait for other object types (threads, processes, mutexes, timers, etc.). You can use a debugger to see that `WaitForMultipleObjectsEx()` and `MsgWaitForMultipleObjectsEx()` call different NT Native API entrypoints (at least on Vista).
bk1e