For this exercise you are to write multithreaded C
programs that simulate car races.
Part 1
The first program simulates a simple car race. The goal is
to determine the winner of the race after all cars have completed the required
number of rounds.
The operation of the program should be as follows: The user
will run the program and will enter on the command line the number of race cars
and the number of laps to go. The program will then create a separate thread
for each racecar. As result the program will print out the position of each
racecars at the end of each lap.
- Input: number of laps to go, number of racecars
- Output: Position of each racecar at the end of each lap
(winner first, loser last)
Example
$formula1 50, 10
Lap 1: 5,7,1,2,9,4,8,3,6,10
Lap 2: 7,5,3,9,4,2,8,1,10,6
Lap 3: 7,5,1,4,3,2,9,8,10,6
Lap 4: 3,5,7,9,4,8,2,1,10,6
...
Lap 50: 2,5,7,1,9,4,8,10,3,6
END
Hints
- Each racecar should be implemented as an independent thread.
- The different speeds of racecars can be modeled in several ways, for example:
- By periodically putting each thread to sleep for a random amount of time.
- By periodically advancing each racecar by a random distance.
- By periodically calling the yield method.
- By using thread priorities.
- By a combination of any of these methods above.
Part 2
The second program simulates a car race with accidents.
An accident is a random occurrence that involves two
racecars. Both racecars involved in an accident are so badly damaged that they
can't continue the race and thus do not cross the finish line.
The operation of the program should be as follows: The user
will run the program and will enter on the command line the number of race
cars, the number of laps to go, and the maximum number of accidents. The
program will then create a separate thread for each racecar. As result the
program will print the accidents that occurred and the position of the racecars
at the end of each lap.
- Input: number of laps to go, number of racecars, maximum number of accidents
- Output: List of accidents and position of each racecar at the end of each lap
(winner first, loser last).
Example:
$formula2 10, 60, 2
Lap 1:
Positions: 5,7,1,2,9,4,8,3,6,10
Lap 2:
Positions: 7,5,3,9,4,2,8,1,10,6
Lap 3:
Accident: (9,4)
Positions: 7,5,1,3,2,8,10,6
Lap 4:
Positions: 3,5,7,8,2,1,10,6
...
Lap 16:
Accident: (1,2)
Positions: 3,5,7,8,10,6
...
Lap 60:
Positions: 5,7,8,10,3,6
END
Hint
The occurrence of an accident and the cars involved in it can be determined at
random.
Part 3
The third program simulates a race with racing teams and pit
stops. Each racing team has two or more racecars whose fuel
consumption is monitored by the engineers at the pit. Whenever a car is low on
fuel the crew chief notifies the driver to come in for a pit stop.
Unfortunately, each team has only one refilling station so that only one car
can be refueled at each time.
- The fuel consumption per car is random.
- The time it takes to refuel a car is random.
- A car that runs out of gas drops out of the race.
The operation of the program should be as follows: The user
will run the program and will enter on the command line the number of teams,
the number of race cars per team and the number of laps to go. The program will
then create a separate thread for each team and for each racecar. As result the
program will print out the positions after each lap and the following events:
- A car is being refueled
- A car runs out of fuel
Example:
$formula3 5, 4, 60
Lap 1:
Positions: 5,7,1,2,9,4,8,3,6,10
Lap 2:
Positions: 7,5,3,9,4,2,8,1,10,6
Lap 3:
Refueling: 5
Refueling: 4
Refueling: 10
Refueling: 6
No gas: 2
Positions: 7,5,3,9,4,8,1,10,6
Lap 4:
Refueling: 8
Refueling: 9
Refueling: 10
Refueling: 4
Refueling: 6
No gas: 1
No gas: 9
Positions: 5,7,4,8,3,6,10
...
Lap 50:
Refueling: 10
Refueling: 8
No gas: 3
Refueling: 10
Refueling: 7
Positions: 5,8,7,6,10
END
Part 4
The purpose of this part is to familiarize you with synchronization primitives
(synchronized, wait(), notify(), notifyall()) and to train you in solving common synchronization problems
(race conditions, mutual exclusion, critical sections, deadlocks etc., see Chap. 8)
You are to develop a solution for a slight variation of Part 3. This time, you are
asked to use synchronization primitives to make sure that no synchronization errors occur.
As a slight change from Part 3, you are asked to develop a solution with the following characteristics:
- Racecars that are low on fuel are either refilled immediately (if the station is
empty) or line up to be refilled (if the station is occupied by another
car). Thus no car will ever run out of fuel.
- The decision to refuel or not to refuel is made by each racecar driver
individually, not by a racing team.
These changes actually make the problem easier if synchronization is used properly.
The following characteristics stay the same:
- The fuel consumption per car is random.
- The time it takes to refuel a car is random.
The operation of the program should be as follows: The user
will run the program and will enter on the command line the number of teams,
the number of race cars per team and the number of laps to go. The program will
then create a separate thread for each racecar. As result the program will
print out the racecar positions at each lap and the following events:
- A car enters a filling station
- A car leaves a filling station
- A car lines up in front of a filling station to be refueled.
Example:
$formula4 5 2 60
Lap 1:
Positions: 5,7,1,2,9,4,8,3,6,10
...
Lap 12:
Car 1 enters station 1
Car 6 enters station 3
Car 2 waits for station 1
Car 1 leaves station 1
Car 2 enters station 1
Car 6 leaves station 3
Car 2 leaves station 1
Positions: 7,5,3,9,4,2,8,1,10,6
...
Lap 60:
Positions: 3,5,7,9,4,8,10,6,4,9
END
General Program Requirements
- Each program must satisfy the following requirements:
- There is one thread for each racecar.
- The winner of a race is determined at random.
- If run often enough, each program will eventually simulate every possible race outcome.
- Each program runs equally well on cooperative and
multithreaded operating systems
- No program uses depreciated methods (Thread.stop() etc.)