Известная проблема американских горок. Предположим, что есть n пассажиров и
одна машина американских горок. Пассажиры многократно ждут, чтобы покататься
на машине. Автомобиль имеет вместимость C мест, C
В машине должна быть нить, которая ждет, пока пассажиры С не войдут в машину.
для поездки, затем ходит по трассе в течение определенного промежутка времени
(некоторое фиксированное время сна), а затем позволяет пассажирам высадиться. Оно делает
до тех пор, пока не останется пассажиров, желающих покататься.
Ваш поток main () будет выполнять pthread_join () в потоке машины.
Когда больше нет ожидающих пассажирских нитей, автомобильная нить выходит
и, таким образом, поток main () напечатает что-то информативное и завершится.
Итак, предположим, что автомобиль и каждый пассажир представлены отдельными
потоки. Как бы вы написали программу, которая может симулировать эту систему
и выполнить следующие требования:
Автомобиль всегда едет точно с пассажирами C;
Пассажиры не спрыгнут с машины во время движения;
Пассажиры не будут прыгать на машине во время движения;
Потоки должны синхронизироваться с помощью «монитора» (помните, это
использует взаимное исключение и условную переменную, чтобы гарантировать взаимное исключение)
которая имеет три операции: takeRide, loadCustomers и
unloadCustomers. Первая операция вызвана пассажирами; вызов
не возвращается, пока пассажир не прокатится и не будет готов
Покидать. Последние две операции вызываются потоком машины. Ты можешь
добавить что-нибудь еще, чтобы помочь вашей проектной работе.
Моя проблема: Это функции для передачи в потоки. takeRide
передается в пассажирские потоки, нагрузка и выгрузка передаются в автомобильную резьбу. Во-первых, есть комбинации пассажиров и вместимости машины, которые не будут работать. Например, вместимостью 2 на машину и 7 пассажиров. Это застрянет на последнем пассажире. Во-вторых, выгрузка не работает должным образом. Я не вижу "пассажир х оставил машину". Как я могу решить эту проблему, чтобы она не работала для каждой комбинации пассажир / грузоподъемность? Нужен ли мне еще mutex
? Кроме того, почему он просто перестает работать случайным образом, как в примере ниже? И почему carUnload не работает должным образом?
Пример выходного тупика: вместимость = 2, пассажиры = 6
Passenger 5 is waiting for car.
Passenger 4 is waiting for car.
Passenger 3 is waiting for car.
Passenger 2 is waiting for car.
Passenger 1 is waiting for car.
Passenger 0 is waiting for car.
Car is waiting for passengers.
Passenger 4 will take ride in the car
Passenger 3 will take ride in the car
Passenger 2 is waiting for car.
Passenger 1 is waiting for car.
Passenger 5 is waiting for car.
Passenger 0 is waiting for car.
.h
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
int cap, numPass;
int passengersInCar;
bool carIsWaiting; //true if car is waiting for passengers
pthread_mutex_t rollerCoasterLock;
pthread_cond_t carLoad;
pthread_cond_t carUnload;
pthread_cond_t carFull;
.C
void takeRide(const int passenger_id);
void load();
void unload();
void takeRide(const int passenger_id){
pthread_mutex_lock(&rollerCoasterLock);
while(!carIsWaiting || passengersInCar==cap){
printf("Passenger %d is waiting for car.\n", passenger_id);
pthread_cond_wait(&carLoad, &rollerCoasterLock);
}
// numPass--;
passengersInCar++;
printf("Passenger %d will take ride in the car\n", passenger_id);
if (passengersInCar == cap){
pthread_cond_broadcast(&carFull);
// passengersInCar=0;
}
pthread_cond_wait(&carFull, &rollerCoasterLock);
pthread_cond_wait(&carUnload, &rollerCoasterLock);
printf("Passenger %d left car.\n", passenger_id);
pthread_mutex_unlock(&rollerCoasterLock);
pthread_exit(0);
}
void load(){
pthread_mutex_lock(&rollerCoasterLock);
// if(numPass==0)
// pthread_exit(NULL);
while(passengersInCar>0){
pthread_cond_wait(&carUnload, &rollerCoasterLock);
}
carIsWaiting = true;
pthread_cond_broadcast(&carLoad);
printf("Car is waiting for passengers.\n");
pthread_cond_wait(&carFull, &rollerCoasterLock);
carIsWaiting = false;
pthread_cond_broadcast(&carFull);
printf("Car is full. Going around...\n" );
pthread_mutex_unlock(&rollerCoasterLock);
}
void unload(){
pthread_mutex_lock(&rollerCoasterLock);
pthread_cond_broadcast(&carUnload);
puts("unloading...");
passengersInCar=0;
pthread_mutex_unlock(&rollerCoasterLock);
// pthread_exit(0);
}
Main
#include <pthread.h>
#include <unistd.h>
#include "rollerCoaster.h"
void* carThreadFunction();
void* passengerThreadFunction(int passenger_id);
void testRollerCoasterOneCar(int carCapacity, int numPassengers);
int cap, numPass;
pthread_attr_t threadAttributes;
int main(int argc, char *argv[]) {
passengersInCar = 0;
carIsWaiting = false;
pthread_mutex_init(&rollerCoasterLock, NULL);
pthread_cond_init(&carLoad, NULL);
pthread_cond_init(&carUnload, NULL);
pthread_cond_init(&carFull, NULL);
//check command line args
if (argc != 3){
puts("Please enter (car-capacity-num) and (num-of-passengers).\n");
exit(0);
} else {
cap = atoi(argv[1]);
numPass = atoi(argv[2]);
}
pthread_attr_init(&threadAttributes);
pthread_attr_setscope(&threadAttributes, PTHREAD_SCOPE_SYSTEM);
testRollerCoasterOneCar(cap, numPass);
pthread_join(carThread, NULL);
puts("done");
return 0;
}
void testRollerCoasterOneCar(int carCapacity, int numPassengers) {
// rollerCoasterOneCar = new RollerCoasterOneCar(carCapacity);
pthread_t carThread;
pthread_create(&carThread, &threadAttributes, (void*) carThreadFunction, (void*) NULL);
pthread_t passengersThreads[numPassengers];
for (int i = 0; i < numPassengers; i++) {
pthread_create(&passengersThreads[i], &threadAttributes, (void*) passengerThreadFunction, (void*)i);
}
}
void* carThreadFunction(){
while(true){
load();
usleep(100000);
unload();
}
return NULL;
}
void* passengerThreadFunction(int passenger_id){
while(true){
takeRide(passenger_id);
}
return NULL;
}