The class Metrowerks::thread represents a thread of execution.
class thread { public: thread(); explicit thread(const std::tr1::function<void ()>& f); explicit thread(void (*f)()); ~thread(); bool operator==(const thread& rhs) const; bool operator!=(const thread& rhs) const; void join(); static void sleep(const universal_time& unv_time); static void sleep(const elapsed_time& elps_time); static void yield(); };
A default constructed thread object represents the current thread. You can create a new thread of execution by passing a general function object, or a simple function pointer. In either case, the function must take no parameters and return void. When a thread destructs, it "detaches" the thread of execution (to use Posix-threads terminology). Once this happens, the thread is independent. You will no longer be able to refer to it, and it will clean up after itself when it terminates. But should main terminate before the thread does, the program ends anyway. You can have one thread wait on another with the join() member function.
#include <ewl_thread> #include <iostream> void do_something() { std::cout << "Thread 1! } int main() { Metrowerks::thread t1(do_something); t1.join(); }
In the above example, main will wait for (join with) t1. Note that global objects like std::cout must be protected if more than one thread is going to access it. You must do this work yourself.
#include <ewl_thread> #include <iostream> Metrowerks::mutex cout_mutex; void do_something() { Metrowerks::mutex::scoped_lock lock(cout_mutex); std::cout << "Thread 1! } void do_something_else() { Metrowerks::mutex::scoped_lock lock(cout_mutex); std::cout << "Thread 2! } int main() { std::cout << "Main Metrowerks::thread t1(do_something); Metrowerks::thread t2(do_something_else); t1.join(); t2.join(); }
In this example, each thread locks cout_mutex before using cout. main() didn't have to lock cout because no other threads started until after main() was done with cout.
You can also have threads sleep, but using a mutex and/or a condition variable (described in Condition Variables ) is almost always a better solution. Similarly for thread::yield which is really just a convenience function for calling sleep with elapsed_time(0).
In single thread mode, creating a thread is equivalent to a synchronous function call (though not nearly as efficient).
If you have multiple threads to create, you can create a Metrowerks::thread_group.
class thread_group { public: thread_group(); ~thread_group(); const thread* create_thread(const thread::func_type& f); void join_all(); };
The main feature of thread_group is that it makes it very easy to join with all of the threads.
int main() { std::cout << "Main Metrowerks::thread_group g; g.create_thread(do_something); g.create_thread(do_something_else); g.join_all(); }