The (rather unsightly) code mass for the example is in the following files:
The templated class allows you to define a (circular) buffer for whatever kind of data you want to store. Your main application could declare SharedBuffer<string> if you wanted to save messages as C++ strings, SharedBuffer<char*> if you wanted to save them as character arrays, etc.
The main routine in the threadTest.C application creates 5 threads that produce data and 5 that consume data (set in the constants at the start of that file) as well as a single shared circular buffer (of floats in this case) that the producers stick data into and the consumers read data from.
The pthread library is used for thread creation and semaphores are used to restrict access to the global buffer: only one thread (whether a producer or consumer) can access the buffer at any given instant.
The shared buffer has one mutex lock on the actual array storing the data and another for locking out access to the index positions (front/back/size/current).
Note that there is also a mutex on communication access (reading from the keyboard/writing to the terminal) to ensure that the I/O from different producers/consumers doesn't get mixedup.
Because of the use of a templated class for the buffer, all the templated method implementations are included in the .h file.
The objective for this lab is to see if you can get a listener to receive messages in one thread, putting them into the buffer, while your main application (in another thread) can process messages once they're in the queue.
(Or, similarly, get two threads going in the client - one to read messages from the user and put them in the buffer, the other checking the buffer and sending messages when it finds something there to send.)
For a quick rehash on pthreads:
In this example the argument is just an integer id
to tell the thread who they are, but in general you'll
probably want to pass more info.
One approach is to define a struct composed of all the data you want to pass to that kind of thread, create/initialize the struct in your main (or whichever routine controls the threads) and (void*) that. The thread routine would then cast the void* it receives back to whatever kind of struct it's expecting, and access the fields appropriately. Specifically in the case of this program, rather than having a single global shared buffer, you might create the buffer in the main routine and include a pointer to it as part of the passed struct. |
For a quick rehash on mutexes in pthread: