免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1567 | 回复: 0

[学习分享] 新手求助,Linux下二人过河问题,求大神指导下我写的代码 [复制链接]

论坛徽章:
2
水瓶座
日期:2014-06-12 08:22:39IT运维版块每日发帖之星
日期:2015-08-05 06:20:00
发表于 2014-11-06 21:14 |显示全部楼层
10可用积分
本帖最后由 陌路巨额投入 于 2014-11-06 21:16 编辑

过桥问题
一座小桥(最多只能承重2个人)横跨南北两岸,任意时刻同一方向只允许一个人过桥,南侧桥段和北侧桥段较窄只能通过一人,桥中央一处宽敞,允许两个人通过或歇息。因此,过桥问题就是采用某种机制,使得两岸的人可以顺利地过桥,同时又能保证桥的安全性。
根据上述对于过桥问题的描述,使用Linux的信号量机制编程解决该问题。通过本课设掌握Linux进程创建的方法,掌握信号量使用方法。
要求实现以下功能。
        编写2段程序,程序1创建3个子进程,分别编号A、B、C,用于模拟从南岸前往北岸的人;程序2创建3个子进程,分别编号C、D、E,用于模拟从北岸前往南岸的人。
        通过向屏幕输出语句模拟过桥过程,如输出“南往北-到桥中间”表示从南岸前往北岸的人到达了桥中间;输出“南往北-到达北岸”表示从南岸前往北岸的人到达了北岸。通过观察输出语句,可以发现过桥时是否发成冲突。
        使用Linux的信号量机制,编写解决过桥问题的代码。
        要求给出编译所用到的makefile文件。


我的错误是:在使用Makefile编译的时候提示:多次定义main 多次定义sem_p以及多次定义sem_v...求各位大神指导下...
    我写的代码:

/* sem_com.h */

#ifndef                SEM_COM_H
#define                SEM_COM_H

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <semaphore.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);
/*定义三个信号量 load用来控制桥上人数,初值为2,表示桥上最多有2人;
  north用来控制北段桥的使用,初值为1,用于对北段桥互斥;
  south用来控制南段桥的使用,初值为1,用于对南段桥互斥。*/
int load = 2, north = 1, south = 1;

#endif /* SEM_COM_H */


/* sem_com.c */

#include "sem_com.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)
        {
                perror(" 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;

        if (semop(sem_id, &sem_b, 1) == -1)
        {
                perror("V operation";
                return -1;
        }
        return 0;
}


/* NorthtoSouth.c */
#include "sem_com.h"

int main(void)
{
        pid_t pid_A, pid_B, pid_C;

        /*调用fork函数创建第一个子进程A,其返回值为pid_A*/
        pid_A = fork();
        /*通过pid_A的值来判断fork函数的返回情况,首先进行出错处理*/
        if(pid_A ==  -1)
        {
                perror("Fork\n";
        }
        else if (pid_A == 0) /*返回值为0代表子进程*/
        {
                //P操作信号量load和south
                sem_p(load);
                sem_p(south);
                printf("\nA从南往北-过南桥段\n";

                //V操作信号量south
                sem_v(south);
                printf("\nA从南往北-到桥中间\n";

                //P操作信号量north
                sem_p(north);
                printf("\nA从南往北-过北桥段\n";

                //V操作信号量north和load
                sem_v(north);
                sem_v(load);
                printf("\nA从南往北-到达北岸\n";
               

        }

        /*调用fork函数创建第二个子进程B,其返回值为pid_B*/
        pid_B = fork();
        /*通过pid_B的值来判断fork函数的返回情况,首先进行出错处理*/
        if(pid_B ==  -1)
        {
                perror("Fork\n";
        }
        else if (pid_B == 0) /*返回值为0代表子进程*/
        {
                        //P操作信号量load和south
                sem_p(load);
                sem_p(south);
                printf("\nB从南往北-过南桥段\n");

                //V操作信号量south
                sem_v(south);
                printf("\nB从南往北-到桥中间\n");

                //P操作信号量north
                sem_p(north);
                printf("\nB从南往北-过北桥段\n");

                //V操作信号量north和load
                sem_v(north);
                sem_v(load);
                printf("\nB从南往北-到达北岸\n");


        }

        /*调用fork函数创建第三个子进程C,其返回值为pid_C*/
        pid_C = fork();
        /*通过pid_C的值来判断fork函数的返回情况,首先进行出错处理*/
        if(pid_C ==  -1)
        {
                perror("Fork\n");
        }
        else if (pid_C == 0) /*返回值为0代表子进程*/
        {
                        //P操作信号量load和south
                sem_p(load);
                sem_p(south);
                printf("\nC从南往北-过南桥段\n");

                //V操作信号量south
                sem_v(south);
                printf("\nC从南往北-到桥中间\n");

                //P操作信号量north
                sem_p(north);
                printf("\nC从南往北-过北桥段\n");

                //V操作信号量north和load
                sem_v(north);
                sem_v(load);
                printf("\nC从南往北-到达北岸\n");
        }

        exit(0);
}


/* NorthtoSouth.c */
#include "sem_com.h"

int main(void)
{
        pid_t pid_C, pid_D, pid_E;

        /*调用fork函数创建第一个子进程C,其返回值为pid_C*/
        pid_C = fork();
        /*通过pid_C的值来判断fork函数的返回情况,首先进行出错处理*/
        if(pid_C ==  -1)
        {
                perror("Fork\n");
        }
        else if (pid_C == 0) /*返回值为0代表子进程*/
        {
                //P操作信号量load和north
                sem_p(load);
                sem_p(north);
                printf("\nC从北往南-过北桥段\n");

                //V操作信号量north
                sem_v(north);
                printf("\nC从北往南-到桥中间\n");

                //P操作信号量south
                sem_p(south);
                printf("\nC从北往南-过南桥段\n");

                //V操作信号量south和load
                sem_v(south);
                sem_v(load);
                printf("\nC从北往南-到达南岸\n");
               

        }

        /*调用fork函数创建第二个子进程D,其返回值为pid_D*/
        pid_D = fork();
        /*通过pid_D的值来判断fork函数的返回情况,首先进行出错处理*/
        if(pid_D ==  -1)
        {
                perror("Fork\n");
        }
        else if (pid_D == 0) /*返回值为0代表子进程*/
        {
                //P操作信号量load和north
                sem_p(load);
                sem_p(north);
                printf("\nD从北往南-过北桥段\n");

                //V操作信号量north
                sem_v(north);
                printf("\nD从北往南-到桥中间\n");

                //P操作信号量south
                sem_p(south);
                printf("\nD从北往南-过南桥段\n");

                //V操作信号量south和load
                sem_v(south);
                sem_v(load);
                printf("\nD从北往南-到达南岸\n");


        }

        /*调用fork函数创建第三个子进程E,其返回值为pid_E*/
        pid_E = fork();
        /*通过pid_E的值来判断fork函数的返回情况,首先进行出错处理*/
        if(pid_E ==  -1)
        {
                perror("Fork\n");
        }
        else if (pid_E == 0) /*返回值为0代表子进程*/
        {
                //P操作信号量load和north
                sem_p(load);
                sem_p(north);
                printf("\nE从北往南-过北桥段\n");

                //V操作信号量north
                sem_v(north);
                printf("\nE从北往南-到桥中间\n");

                //P操作信号量south
                sem_p(south);
                printf("\nE从北往南-过南桥段\n");

                //V操作信号量south和load
                sem_v(south);
                sem_v(load);
                printf("\nE从北往南-到达南岸\n");
        }

        exit(0);
}

Makefile文件。

EXEC = NorthtoSouth SouthtoNorth
OBJS = NorthtoSouth.o SouthtoNorth.o sem_com.o
HEADERS = sem_com.h

CC = gcc
INC = -I.
CFLAGS = ${INC} -g

all{EXEC}
${EXEC} : ${OBJS}
        ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${OBJS}

${OBJS} : ${HEADERS}

.PHONY : clean
clean :
        -rm -f ${OBJS} ${EXEC}


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会,8.5折限时优惠重磅来袭!
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。

限时8.5折扣期:2019年9月30日前


----------------------------------------

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP