过桥问题一座小桥(最多只能承重2个人)横跨南北两岸,任意时刻同一方向只允许一个人过桥,南侧桥段和北侧桥段较窄只能通过一人,桥中央一处宽敞,允许两个人通过或歇息。因此,过桥问题就是采用某种机制,使得两岸的人可以顺利地过桥,同时又能保证桥的安全性。(1)根据上述对于过桥问题的描述,使用Linux的信号量机制编程解决该问题。通过本课设掌握Linux进程创建的方法,掌握信号量使用方法。(2)设计要求设计的系统要求实现以下功能。l 编写2段程序,程序1创建3个子进程,分别编号A、B、C,用于模拟从南岸前往北岸的人;程序2创建3个子进程,分别编号C、D、E,用于模拟从北岸前往南岸的人。l 通过向屏幕输出语句模拟过桥过程,如输出“南往北-到桥中间”表示从南岸前往北岸的人到达了桥中间;输出“南往北-到达北岸”表示从南岸前往北岸的人到达了北岸。通过观察输出语句,可以发现过桥时是否发成冲突。l 使用Linux的信号量机制,编写解决过桥问题的代码。l 要求给出编译所用到的makefile文件。
这个题目。。我写的代码。。能够单方面运行成功,合在一起就不可以。。求教各位Linux大神,。。如何解决啊?
/* NorthtoSouth.c */
#include "move.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
/*
*函数类型:北岸去南岸进程函数
*功能:北岸前往南岸人的进程,并创建3个子进程充当3个人
*/
int main(void)
{
int load, south, north;
pid_t pid_C, pid_D, pid_E;
/* 获得信号量 */
load = semget(ftok(".", 'a'), 1, 0666); //获得load信号量
south = semget(ftok(".", 'b'), 1, 0666); //获得south信号量
north = semget(ftok(".", 'c'), 1, 0666); //获得north信号量
if (load == -1)
{
perror("SouthtoNorth is'nt exist");
}
if (south == -1)
{
perror("SouthtoNorth is'nt exist");
exit(1);
}
if (north == -1)
{
perror("SouthtoNorth is'nt exist");
exit(1);
}
/*调用fork函数创建第一个子进程C,其返回值为pid_C*/
pid_C = fork();
/*调用fork函数创建第二个子进程D,其返回值为pid_D*/
pid_D = fork();
/*调用fork函数创建第三个子进程E,其返回值为pid_E*/
pid_E = fork();
/*通过pid_C的值来判断fork函数的返回情况,首先进行出错处理*/
do
{
if(pid_C == -1)
{
exit(1); //异常退出
}
else if (pid_C == 0) /*返回值为0代表子进程*/
{
//P操作信号量load和north
sem_p(load);
sem_p(north);
printf("
CNorth To South-pass North bridge
");
//V操作信号量north
sem_v(north);
printf("
CNorth To South-arrive bridge Center
");
//P操作信号量south
sem_p(south);
printf("
CNorth To South-pass South bridge
");
//V操作信号量south和load
sem_v(south);
sem_v(load);
printf("
CSouth To North-arrive South
");
}
/*通过pid_D的值来判断fork函数的返回情况,首先进行出错处理*/
if(pid_D == -1)
{
exit(1); //异常退出
}
else if (pid_D == 0) /*返回值为0代表子进程*/
{
//P操作信号量load和north
sem_p(load);
sem_p(north);
printf("
DNorth To South-pass North bridge
");
//V操作信号量north
sem_v(north);
printf("
DNorth To South-arrive bridge Center
");
//P操作信号量south
sem_p(south);
printf("
DNorth To South-pass South bridge
");
//V操作信号量south和load
sem_v(south);
sem_v(load);
printf("
DSouth To North-arrive South
");
}
/*通过pid_E的值来判断fork函数的返回情况,首先进行出错处理*/
if(pid_E == -1)
{
exit(1); //异常退出
}
else if (pid_E == 0) /*返回值为0代表子进程*/
{
//P操作信号量load和north
sem_p(load);
sem_p(north);
printf("
ENorth To South-pass North bridge
");
//V操作信号量north
sem_v(north);
printf("
ENorth To South-arrive bridge Center
");
//P操作信号量south
sem_p(south);
printf("
ENorth To South-pass South bridge
");
//V操作信号量south和load
sem_v(south);
sem_v(load);
printf("
ESouth To North-arrive South
");
}
exit(0);
}
/* SouthtoNorth.c */
#include "move.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MYFIFO "myfifo"
void *SouthtoNorth(void *arg);
void *NorthtoSouth(void *arg);
int fd; //有名管道标识符
/*
*函数类型:主函数main
*功能:创建信号量 初始化信号量 调用两个子进程的函数
*/
int main()
{
int load, south, north;
pid_t pid_A, pid_B, pid_C;
load = semget(ftok(".", 'a'), 1, 0666|IPC_CREAT); //创建一个信号量
south = semget(ftok(".", 'b'), 1, 0666|IPC_CREAT); //创建一个信号量
north = semget(ftok(".", 'c'), 1, 0666|IPC_CREAT); //创建一个信号量
init_sem(load,2); //初始化共享信号量load为2
init_sem(south,1); //初始化南岸互斥信号量为1
init_sem(north,1); //初始化北岸互斥信号量为1
/*创建有名管道*/
if((mkfifo(MYFIFO, O_CREAT|O_EXCL) < 0) && (errno != EEXIST))
{
printf("Cannot create fifo
");
}
/*打开管道*/
fd = open(MYFIFO, O_RDWR);
if (fd == -1)
{
printf("Open fifo error
");
return fd;
}
/*调用fork函数创建第一个子进程A,其返回值为pid_A*/
pid_A = fork();
/*调用fork函数创建第二个子进程B,其返回值为pid_B*/
pid_B = fork();
/*调用fork函数创建第三个子进程C,其返回值为pid_C*/
pid_C = fork();
/*通过pid_A的值来判断fork函数的返回情况,首先进行出错处理*/
if(pid_A == -1)
{
exit(1); //异常退出
}
else if (pid_A == 0) /*返回值为0代表子进程*/
{
//P操作信号量load和south
sem_p(load);
sem_p(south);
printf("
ASouth To North-pass South bridge
");
//V操作信号量south
sem_v(south);
printf("
ASouth To North-arrive bridge Center
");
//P操作信号量north
sem_p(north);
printf("
ASouth To North-pass North bridge
");
//V操作信号量north和load
sem_v(north);
sem_v(load);
printf("
ASouth To North-arrive North
");
}
/*通过pid_B的值来判断fork函数的返回情况,首先进行出错处理*/
if(pid_B == -1)
{
exit(1);
}
else if (pid_B == 0) /*返回值为0代表子进程*/
{
//P操作信号量load和south
sem_p(load);
sem_p(south);
printf("
BSouth To North-pass South bridge
");
//V操作信号量south
sem_v(south);
printf("
BSouth To North-arrive bridge Center
");
//P操作信号量north
sem_p(north);
printf("
BSouth To North-pass North bridge
");
//V操作信号量north和load
sem_v(north);
sem_v(load);
printf("
BSouth To North-arrive North
");
}
/*通过pid_C的值来判断fork函数的返回情况,首先进行出错处理*/
if(pid_C == -1)
{
exit(1);
}
else if (pid_C == 0) /*返回值为0代表子进程*/
{
//P操作信号量load和south
sem_p(load);
sem_p(south);
printf("
CSouth To North-pass South bridge
");
//V操作信号量south
sem_v(south);
printf("
CSouth To North-arrive bridge Center
");
//P操作信号量north
sem_p(north);
printf("
CSouth To North-pass North bridge
");
//V操作信号量north和load
sem_v(north);
sem_v(load);
printf("
CSouth To North-arrive North
");
}
exit(0);
}
/* move.c */
#include "move.h"
int init_sem(int sem_id, int init_value)
{
union semun sem_union;
sem_union.val = init_value;
if (semctl(sem_id, 0, SETVAL, sem_union) == -1)
{
perror("Initialize semaphore");
return -1;
}
return 0;
}
int del_sem(int sem_id)
{
union semun sem_union;
if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
{
perror("Delete semaphore");
return -1;
}
}
int sem_p(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0; /*id*/
sem_b.sem_op = -1; /* P operation*/
sem_b.sem_flg = SEM_UNDO;
if (semop(sem_id, &sem_b, 1) == -1) /*1:first struct*/
{
perror("P operation");
return -1;
}
return 0;
}
int sem_v(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0; /* id */
sem_b.sem_op = 1; /* V operation */
sem_b.sem_flg = SEM_UNDO; /* It's tracks be follow, to automatical free for it*/
if (semop(sem_id, &sem_b, 1) == -1)
{
perror("V operation");
return -1;
}
return 0;
}
/* sem_com.h */
#ifndef SEM_COM_H
#define SEM_COM_H
#include <sys/ipc.h>
#include <sys/sem.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
int init_sem(int, int);
int del_sem(int);
int sem_p(int);
int sem_v(int);
#endif /* SEM_COM_H */
Makefile文件。。。。
EXEC1 = SouthtoNorth
EXEC2 = NorthtoSouth
OBJS1 = SouthtoNorth.o move.o
OBJS2 = NorthtoSouth.o move.o
HEADERS = move.h
CC = gcc
CFLAGS = -O2
all:${EXEC1} ${EXEC2}
${EXEC1} : ${OBJS1}
${CC} ${CFLAGS} ${LDFLAGS} -o $@ $^
${EXEC2} : ${OBJS2}
${CC} ${CFLAGS} ${LDFLAGS} -o $@ $^
${OBJS1} : ${HEADERS}
${OBJS2} : ${HEADERS}
.PHONY : clean
clean :
-rm -f ${OBJS1} ${EXEC1}
-rm -f ${OBJS2} ${EXEC2}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>