着名的过山车问题 . 假设有n名乘客和一辆过山车 . 乘客反复等待乘坐汽车 . 这辆车有C座位,C <n,但是小车主不会让车离开车站,直到它满了 . 编写程序来模拟此问题的解决方案 . 每位乘客必须是一个等待乘车的线程,等待乘车完成,从乘车下机并离开 . 汽车应该是一个等待C乘客进入汽车乘坐的线程,然后绕轨道行驶一段固定的时间(一些固定的睡眠时间),然后让乘客下机 . 这样做直到没有更多的乘客想要乘坐 . 你的main()线程将在汽车线程上执行pthread_join() . 当没有更多等待的乘客线程时,汽车线程退出,因此main()线程将打印信息并退出 . 因此,假设汽车和每位乘客都由不同的线程代表 . 你会如何编写一个可以模拟这个系统并满足以下要求的程序:汽车总是和C乘客一起乘坐;汽车行驶时,没有乘客会从车上跳下来;汽车行驶时,没有乘客会跳上车;线程将通过“监视器”进行同步(请记住,它使用互斥锁和条件变量来保证互斥),它有三个操作:takeRide,loadCustomers和unloadCustomers . 第一次行动由乘客召集;在乘客乘坐并准备离开之前,呼叫不会返回 . 最后两个操作由汽车线程调用 . 您可以添加任何其他内容以帮助您的设计工作 .
My problem: 这些是要传递给线程的函数 . takeRide
被传递到乘客线程,加载和卸载被传递到汽车线程 . 首先,乘客和汽车容量的组合是行不通的 . 例如,汽车和7名乘客的容量为2 . 这将被困在最后一位乘客身上 . 其次,unboarding没有看到"passenger x left car."如何解决这个问题不适用于每个乘客/容量组合?我需要另一个 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);
}
主要
#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;
}