views:

415

answers:

2

I'm trying to replace some thread communication with a custom queue, producer is currently using PostThreadMessage, consumer is using WaitForSingleObject/PeekMessage.

http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html would be what I needed, but boost nor C++ is not an option.

Not wanting to reimplement the wheel, does anyone have such a queue implemented in C ?

A: 

The PostThreadMessage/WaitForSingleObject is the appropriate way to do message queuing between threads on win32.

You can also use SetEvent() (from the producer) and WaitForSingleObject() (or WaitForMultipleObjects() if multiple queues) (in the consumer) to send a flag saying that a custom queue you've written has items.

The following pseudo-code describes this approach:

in producer...
   ...
   create item
   acquire_lock
   push item onto queue
   release_lock
   SetEvent(...)
   ...

in consumer...
   while(true)
      WaitForSingleObject(event)
      acquire_lock
      pop item from queue
      release_lock
      process item
      release item
Will
They're heavyweight. By quite a lot compared to what a custom queue *could* be. You can't(easily) specify semantics such as the max queued elements, how the queue should behave when that limit is reached. You can't have more than 1 queue per thread, etc.
nos
Well I'll edit it to address these exact comments
Will
Thanks, but I'm not really looking for pseudo code. I could implement this myself, and spend a couple of days debugging race conditions and deadlocks (these things can get quite complicated if you also want the producer to block at a given limit, support multiple producers, juggling internal queue nodes in a memory pool for less memory management overhead etc.) - but I'd like to avoid that if possible. I merely want to see if anyone has existing solutions out there.
Anonym
+2  A: 

Use an IO Completion Port (see here) as your queue; they don't need to be just related to I/O operations and are very easy to use and perform very well due to the way the kernel can be set to limit the number threads that run in your thread pool.

Basically you call PostQueuedCompletionStatus() to put items on the queue and GetQueuedCompletionStatus() to take them off. You don't need to worry about synchronisation etc.

If you need a little more help in getting it to work then you could take a look at my free high performance server framework which includes quite a lot of IOCP code, including a stand alone thread pool that isn't related in any way to I/O. Note that this is in C++ but it should give you a good idea of how the C API hangs together.

Len Holgate
+1 for io completion ports. They are a great mechanism if your code is windows only. The os does lots of nice management for you. We used them quite a bit at Adobe.
tony
+1 for io completion ports. Its a complicated name for a simple api. Its easy to be put off until you realize you *can* pass NULL or zero for almost every parameter and ignore everything in the docs related to handling file io.Of course, they do use their own byzantine internal logic - which is why one needs to double check your worker threads to make sure theyre actually being called.
Chris Becke