Yes you need an explicit thread on the producer side.
Here is what I assume your system is going to look like:
In other words you’ll have multiple processes sending data to your logger. I am further assuming that you don’t want ProcessA to wait until the logger completely processes a log message from ProcessB.
To achieve this on the logger you have 2 choices:
- Have 1 receive thread per process. That means lots of threads in your logger and sorting out lots of thread interaction.
- Have one push(producer)/pull(consumer) thread in your logger. This is the condvar method.
We use option 2 in our system.
To minimize the wait for the sending processes (ProcessA-C) the push(producer) thread needs to basically just receive messages and put them in an internal queue and go back and wait for the next message. The pull(consumer) thread does the work. The condvar is just needed to signal the pull thread there is work to do which was what your original post was about.
OK, now back to the example code I posted far above. In that example code the condvar is being used to signal in BOTH directions. That the queue is empty (for the push thread) AND the queue is non-empty (for the pull thread). You don’t need the empty part because you are implementing a linked list (probably a C++ List class).
So on the push (producer) thread you can eliminate the condvar wait part so that it looks like:
void *producer (void *notused)
printf ("In producer thread...\n");
// get data from producer threads
// we'll simulate this with a sleep (1) but would
// really come from an async MsgReceive() call that
// all your producer processes send to.
printf ("producer: got data to log. Add to queue\n");
// Lock the mutex. Must do this since we are going to manipulate
// The linked list of data AND activate the condvar.
// Add the message to the linked list
data_ready = 1;
// Signal the push(consumer) thread the linked list has at least 1 item
// Unlock the mutex so the push(consumer) thread can access the linked list
This is exactly what my push(producer) thread looks like.
Note: In the pull(consumer) thread you no longer need the
line because you aren’t signaling back to the push(producer) thread to indicate empty list because the push(producer) thread doesn’t care.
Does that make a bit more sense?