Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
The priority of a thread conveys the importance of a
thread to the scheduler. Although the order that the CPU runs a set of threads
is indeterminate, the scheduler will lean toward running the waiting
thread with the highest priority first. However, this doesn t mean that threads
with lower priority aren t run (that is, you can t get deadlocked because of priorities). Lower priority threads just tend to run less often.
Here s MoreBasicThreads.cpp modified so that the
priority levels are demonstrated. The priorities are adjusting by using Thread s
setPriority( ) function.
//: C11:SimplePriorities.cpp
// Shows the use of thread priorities.
//{L} ZThread
#include <iostream>
#include "zthread/Thread.h"
using namespace ZThread;
using namespace std;
const double pi = 3.14159265358979323846;
const double e = 2.7182818284590452354;
class SimplePriorities : public Runnable {
int countDown;
volatile double d; // No optimization
int id;
public:
SimplePriorities(int ident=0): countDown(5),
id(ident) {}
~SimplePriorities() {
cout << id << " completed"
<< endl;
}
friend ostream&
operator<<(ostream& os, const
SimplePriorities& sp) {
return os << "#" << sp.id
<< " priority: "
<< Thread().getPriority()
<< " count: "<<
sp.countDown;
}
void run() {
while(true) {
// An expensive, interruptable operation:
for(int i = 1; i < 100000; i++)
d = d + (pi + e) / double(i);
cout << *this << endl;
if(--countDown == 0) return;
}
}
};
int main() {
try {
Thread high(new SimplePriorities);
high.setPriority(High);
for(int i = 0; i < 5; i++) {
Thread low(new SimplePriorities(i));
low.setPriority(Low);
}
} catch(Synchronization_Exception& e) {
cerr << e.what() << endl;
}
} ///:~
Here, operator<<( ) is overridden to
display the identifier, priority, and countDown value of the task.
You can see that the priority level of thread high is
at the highest level, and all the rest of the threads are at the lowest level.
We are not using an Executor in this example because we need direct
access to the threads in order to set their priorities.
Inside SimplePriorities::run( ), 100,000
repetitions of a rather expensive floating-point calculation are performed,
involving double addition and division. The variable d is volatile
to try to ensure that no compilers optimizations are performed. Without this
calculation, you don t see the effect of setting the priority levels. (Try it:
comment out the for loop containing the double calculations.)
With the calculation, you see that thread high is given a higher
preference by the thread scheduler. (At least, this was the behavior on a
Windows machine.) The calculation takes long enough that the thread scheduling
mechanism jumps in, changes threads, and pays attention to the priorities so
that thread high gets preference.
You can also read the priority of an existing thread with getPriority( ) and change it at any time (not just before the thread is
run, as in SimplePriorities.cpp)
with setPriority( ).
Mapping priorities to operating systems is problematic. For
example, Windows 2000 has seven priority levels, while Sun s Solaris has 231
levels. The only portable approach is to stick to very large priority
granulations, such as the Low, Medium, and High used in
the ZThread library.
Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |