hat is the best way to manage threading in C++ on the Mac?
Pro 9 on the Mac has introduced a new library: Metrowerks::threads,
found in <msl_thread>. This is a thin C++ wrapper over the native OS
threading interface. On Mach-O, Metrowerks::threads relies on
pthreads. On CFM code, Metrowerks::threads calls into Apple's MP
tasks. And soon to be released, the same library will sit on top of
Windows. That is, your application can write to a single threading
interface, but be portable across pthreads, Apple MP tasks and
The Metrowerks::threads lib currently addresses the following issues:
thread local data
exception safe mutex locking/unlocking
initialization / call once
See the MSL C++ Reference for full details.
Below is a simple example of a multithreaded program which deals with
a message queue. One thread feeds messages into the back of a queue,
while another thread reads the messages out of the front. The reading
thread will wait (sleep, not poll) if the queue is empty, and the
sending thread will notify the reading thread if it puts a message
into an empty queue.
The main thread simply creates the sending and receiving threads and
then waits for them to complete their tasks. This is all done with a
high level, intuitive interface.
typedef Metrowerks::mutex Mutex;
typedef Mutex::scoped_lock Lock;
void send (int m);
unbounded_queue::send (int m)
std::cout << "sent: " << m << '\n';
if (the_queue_.size() == 1)
int i = the_queue_.front();
std::cout << "received: " << i << '\n';
int n = 0;
while (n < 1000)
n = buf.receive();
} while (n >= 0);
For this example the "message" is simply an int. A negative int marks
the end of the message stream. The sending and receiving threads
write a message to cout to mark the progress of their work.
The main() function simply starts two threads: send and receive. It
then waits for them to complete with the join() function. Only after
both threads have completed will main exit.
The send thread calls the ordinary function sender() which simply
loops, calling the send() member function of a global unbounded_queue
with the messages 0 ... 999, and then finally sends -1 to indicate
that it is done.
The receive thread calls the ordinary function receiver() which loops
on the unbounded_queue's receive() member function until a negative
number is received.
unbounded_queue is a th