大三上学期操作系统原理这门课中,老师给了一道作业《行人与机动车问题》;
即Linux多线程下处理行人与机动车谁优先的问题,需要用到多线程和互斥量;
假设有一个路口,有很多行人和机动车需要通过,通行交通规则如下:允许多个行人同时通过这个路口,但在任何时候如果有一辆机动车通过,那既不允许行人通过,也不允许其他机动车通过。
在此交通规则下,有2种同步互斥过程,一种是行人优先,即只有没有行人在通过路口且没有其他机动车在通过路口时该机动车才能通过;另一种是机动车优先,如果一个行人申请通过时已有另一辆机动车在等待通过路口,则该行人必须等到没有机动车处于等待状态后才能开始通过。
现在给出行人优先模式的实现过程,模拟效果如下:
输入说明:
每4个字符为一组,代表一次通过,每组第一个字符表示编号,从1开始,逐次递增1;第二字符表示通过类型,W表示行人通过,V表示机动车通过;第三个字符表示到达路口需要的时间;第四个字符表示通过路口需要的时间。
# include
# include
# include
# include
# include
# include
# include
//定义互斥锁
//mutex1用于实现walkmanCount的互斥访问
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
//mutex2用于实现行人和机动车,机动车之间的互斥通过路口
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
int walkmanCount; //行人数量
struct data {
int id; //编号
int opTime;//到达路口的时间
int lastTime;//通过路口需要的时间
};
void* Walkman(void* param) {
int id = ((struct data*)param)->id;
int lastTime = ((struct data*)param)->lastTime;
int opTime = ((struct data*)param)->opTime;
sleep(opTime); //模拟走到路口的过程,沉睡时间等于走到路口的时间
printf("Thread %d: waiting to walk\n", id);
pthread_mutex_lock(&mutex1);
walkmanCount++;
if(walkmanCount == 1)
pthread_mutex_lock(&mutex2);
pthread_mutex_unlock(&mutex1);
printf("Thread %d: start walking\n", id);
sleep(lastTime);//模拟通过的过程,沉睡的时间等于通过的时间
printf("Thread %d: end walking\n", id);
pthread_mutex_lock(&mutex1);
walkmanCount--;
if(walkmanCount == 0)
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
pthread_exit(0);//线程退出一定要有,不然就会成为僵尸线程
}
void* Vehicle(void* param) {
int id = ((struct data*)param)->id;
int lastTime = ((struct data*)param)->lastTime;
int opTime = ((struct data*)param)->opTime;
sleep(opTime);//模拟机动车走到路口的过程
printf("Thread %d: waiting to drive\n", id);
pthread_mutex_lock(&mutex2);
printf("Thread %d: start driving\n", id);
sleep(lastTime);//模拟机动车通过的过程
printf("Thread %d: end driving\n", id);
pthread_mutex_unlock(&mutex2);
pthread_exit(0);//线程退出
}
int main() {
pthread_t tid; // the thread identifier
pthread_attr_t attr; //set of thread attributes
pthread_attr_init(&attr);
walkmanCount = 0;
int id = 0;
while(scanf("%d", &id) != EOF) {
char role;
int opTime;
int lastTime;
scanf("%c%d%d", &role, &opTime, &lastTime);
struct data* d = (struct data*)malloc(sizeof(struct data));
d->id = id;
d->opTime = opTime;
d->lastTime = lastTime;
if(role == 'W') {
printf("Create the %d thread: Walkman\n", id);
pthread_create(&tid, &attr, Walkman, d);
}
if(role == 'V') {
printf("Create the %d thread: Vehicle\n", id);
pthread_create(&tid, &attr, Vehicle, d);
}
}
pthread_mutex_destroy(&mutex1);
pthread_mutex_destroy(&mutex2);
return 0;
}
任务:实现机动车优先模式,即如果一个行人申请通过路口时已有另一机动车在等待通过,则该行人必须等到没有机动车处于等待状态后才能通过路口,实现效果如下:
使用上面行人优先的代码,改为机动车优先的代码!
# include
# include
# include
# include
# include
# include
# include
//定义互斥锁
//mutex1用于实现行人的互斥访问
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
//mutex2用于实现行人和机动车,机动车之间的互斥通过路口
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
// 辅助互斥
pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
int walkmanCount; // 行人数量
int vehicleCount; // 机动车数量
struct data {
int id; //编号
int opTime;//到达路口的时间
int lastTime;//通过路口需要的时间
};
void* Walkman(void* param) {
int id = ((struct data*)param)->id;
int lastTime = ((struct data*)param)->lastTime;
int opTime = ((struct data*)param)->opTime;
sleep(opTime); //模拟走到路口的过程,沉睡时间等于走到路口的时间
printf("Thread %d: waiting to walk\n", id);
pthread_mutex_lock(&mutex1);
walkmanCount++;
if (walkmanCount == 1) {
pthread_mutex_lock(&mutex2);
}
pthread_mutex_unlock(&mutex1);
printf("Thread %d: start walking\n", id);
sleep(lastTime);//模拟通过的过程,沉睡的时间等于通过的时间
printf("Thread %d: end walking\n", id);
pthread_mutex_lock(&mutex3);
walkmanCount--;
if (walkmanCount == 0) {
pthread_mutex_unlock(&mutex2);
}
pthread_mutex_unlock(&mutex3);
pthread_exit(0);//线程退出一定要有,不然就会成为僵尸线程
}
void* Vehicle(void* param) {
int id = ((struct data*)param)->id;
int lastTime = ((struct data*)param)->lastTime;
int opTime = ((struct data*)param)->opTime;
sleep(opTime);//模拟机动车走到路口的过程
printf("Thread %d: waiting to drive\n", id);
pthread_mutex_lock(&mutex3);
if (0 == vehicleCount) {
// 有多辆机动车等待时,只锁mutex1一次
pthread_mutex_lock(&mutex1);
}
vehicleCount++;
pthread_mutex_unlock(&mutex3);
pthread_mutex_lock(&mutex2);
printf("Thread %d: start driving\n", id);
sleep(lastTime);//模拟机动车通过的过程
printf("Thread %d: end driving\n", id);
vehicleCount--;
if (0 == vehicleCount) {
// 机动车没有等待了,解除mutex1的锁
pthread_mutex_unlock(&mutex1);
}
pthread_mutex_unlock(&mutex2);
pthread_exit(0);//线程退出
}
int main() {
pthread_t tid; // the thread identifier
walkmanCount = 0;
vehicleCount = 0;
pthread_mutex_init(&mutex1, 0);
pthread_mutex_init(&mutex2, 0);
pthread_mutex_init(&mutex3, 0);
int id = 0;
while(scanf("%d", &id) != EOF) {
char role;
int opTime;
int lastTime;
scanf("%c%d%d", &role, &opTime, &lastTime);
struct data* d = (struct data*)malloc(sizeof(struct data));
d->id = id;
d->opTime = opTime;
d->lastTime = lastTime;
if(role == 'W') {
printf("Create the %d thread: Walkman\n", id);
pthread_create(&tid, 0, Walkman, d);
}
if(role == 'V') {
printf("Create the %d thread: Vehicle\n", id);
pthread_create(&tid, 0, Vehicle, d);
}
}
pthread_mutex_destroy(&mutex1);
pthread_mutex_destroy(&mutex2);
pthread_mutex_destroy(&mutex3);
return 0;
}
测试案例: