Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
Solutions
to selected exercises can be found in the electronic document The Thinking
in C++ Volume 2 Annotated Solution Guide, available for a small fee from www.MindView.net.
1. Inherit a class from Runnable and override the run( )
function. Inside run( ), print a message, and then call sleep( ).
Repeat this three times, and then return from run( ). Put a
start-up message in the constructor and a shut-down message when the task
terminates. Make several thread objects of this type, and run them to see what
happens.
2. Modify BasicThreads.cpp to make LiftOff threads
start other LiftOff threads.
3. Modify ResponsiveUI.cpp to eliminate any possible race
conditions. (Assume bool operations are not atomic.)
4. In Incrementer.cpp, modify the Count class to use a
single int instead of an array of int. Explain the resulting
behavior.
5. In EvenChecker.h, correct the potential problem in the Generator
class. (Assume bool operations are not atomic.)
6. Modify EvenGenerator.cpp to use interrupt( )
instead of quit flags.
7. In MutexEvenGenerator.cpp, change the code in MutexEvenGenerator::nextValue( )
so that the return expression precedes the release( ) statement and
explain what happens.
8. Modify ResponsiveUI.cpp to use interrupt( )
instead of the quitFlag approach.
9. Look up the Singleton documentation in the ZThreads
library. Modify OrnamentalGarden.cpp so that the Display object
is controlled by a Singleton to prevent more than one Display
from being accidentally created.
10. In OrnamentalGarden.cpp, change the Count::increment( )
function so that it does a direct increment of count (that is, it just
does a count++). Now remove the guard and see if that causes a failure.
Is this safe and reliable?
11. Modify OrnamentalGarden.cpp so that it uses interrupt( )
instead of the pause( ) mechanism. Make sure that your solution
doesn t prematurely destroy objects.
12. Modify WaxOMatic.cpp by adding more instances of the Process
class so that it applies and polishes three coats of wax instead of just one.
13. Create two Runnable subclasses, one with a run( )
that starts and calls wait( ). The other class s run( )
should capture the reference of the first Runnable object. Its run( )
should call signal( ) for the first thread after some number of
seconds have passed so that first thread can print a message.
14. Create an example of a busy wait. One thread sleeps for awhile
and then sets a flag to true. The second thread watches that flag inside
a while loop (this is the busy wait ) and, when the flag becomes true,
sets it back to false and reports the change to the console. Note how
much wasted time the program spends inside the busy wait, and create a second
version of the program that uses wait( ) instead of the busy
wait. Extra: run a profiler to show the time used by the CPU in each case.
15. Modify TQueue.h to add a maximum allowable element count.
If the count is reached, further writes should be blocked until the count drops
below the maximum. Write code to test this behavior.
16. Modify ToastOMaticMarkII.cpp to create peanut-butter and
jelly on toast sandwiches using two separate assembly lines and an output TQueue
for the finished sandwiches. Use a Reporter object as in CarBuilder.cpp
to display the results.
17. Rewrite C07:BankTeller.cpp to use real threading instead
of simulated threading.
18. Modify CarBuilder.cpp to give identifiers to the robots,
and add more instances of the different kinds of robots. Note whether all
robots get utilized.
19. Modify CarBuilder.cpp to add another stage to the
car-building process, whereby you add the exhaust system, body, and fenders. As
with the first stage, assume these processes can be performed simultaneously by
robots.
20. Modify CarBuilder.cpp so that Car has synchronized
access to all the bool variables. Because Mutexes cannot be
copied, this will require significant changes throughout the program.
21. Using the approach in CarBuilder.cpp, model the
house-building story that was given in this chapter.
22. Create a Timer class with two options: (1) a one-shot
timer that only goes off once (2) a timer that goes off at regular intervals.
Use this class with C10:MulticastCommand.cpp to move the calls to TaskRunner::run( )
from the procedures into the timer.
23. Change both of the dining philosophers examples so that the
number of Philosophers is controlled on the command line, in addition to
the ponder time. Try different values and explain the results.
24. Change DiningPhilosophers.cpp so that the Philosophers
just pick the next available chopstick. (When a Philosopher is done with
their chopsticks, they drop them into a bin. When a Philosopher wants to
eat, they take the next two available chopsticks from the bin.) Does this
eliminate the possibility of deadlock? Can you reintroduce deadlock by simply
reducing the number of available chopsticks?