Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
Another way you can control the behavior of your threads is
by calling sleep( ) to cease execution of a thread for a given
number of milliseconds. In the preceding example, if you replace the call to yield( )
with a call to sleep( ), you get the following:
//: C11:SleepingTask.cpp
// Calling sleep() to pause for awhile.
//{L} ZThread
#include <iostream>
#include "zthread/Thread.h"
#include "zthread/ThreadedExecutor.h"
using namespace ZThread;
using namespace std;
class SleepingTask : public Runnable {
int countDown;
int id;
public:
SleepingTask(int ident = 0) : countDown(5), id(ident)
{}
~SleepingTask() {
cout << id << " completed"
<< endl;
}
friend ostream&
operator<<(ostream& os, const
SleepingTask& st) {
return os << "#" << st.id
<< ": " << st.countDown;
}
void run() {
while(true) {
try {
cout << *this << endl;
if(--countDown == 0) return;
Thread::sleep(100);
} catch(Interrupted_Exception& e) {
cerr << e.what() << endl;
}
}
}
};
int main() {
try {
ThreadedExecutor executor;
for(int i = 0; i < 5; i++)
executor.execute(new SleepingTask(i));
} catch(Synchronization_Exception& e) {
cerr << e.what() << endl;
}
} ///:~
Thread::sleep( ) can throw an Interrupted_Exception
(you ll learn about interrupts later), and you can see that this is caught in run( ).
But the task is created and executed inside a try block in main( )
that catches Synchronization_Exception (the base class for all ZThread
exceptions), so wouldn t it be possible to just ignore the exception in run( )
and assume that it will propagate to the handler in main( )? This
won t work because exceptions won t propagate across threads back to main( ).
Thus, you must handle any exceptions locally that may arise within a task.
You ll notice that the threads tend to run in any order,
which means that sleep( ) is also not a way for you to control the order of thread execution. It just stops the execution of the thread for awhile. The
only guarantee that you have is that the thread will sleep at least 100
milliseconds (in this example), but it may take longer before the thread
resumes execution because the thread scheduler still has to get back to it
after the sleep interval expires.
If you must control the order of execution of threads, your
best bet is to use synchronization controls (described later) or, in some
cases, not to use threads at all, but instead to write your own cooperative
routines that hand control to each other in a specified order.
Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |