• 操作系统课程设计--Linux平台哲学家问题


    哲学家问题是操作系统中资源分配的经典问题

    linux平台下的系统api不同于Windows下的实现

    要求:一个正确的哲学家程序(不会发生死锁)

    一个错误的哲学家程序(会发生死锁)

     系统环境:ElementaryOS

    wrong.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/ipc.h>
    #include<sys/msg.h>
    #include<sys/types.h>
    #include<unistd.h>
    #include<errno.h>
    #include<sys/ipc.h>
    #include<sys/sem.h>
    #include<sys/wait.h>
    #define DELAY (rand() % 5 + 1)
    #define ERR_EXIT(m) 
        do { 
            perror(m); 
            exit(EXIT_FAILURE); 
        } while(0)
    
    union semun
    {
        int val;    // Value for SETVAL
        struct semid_ds *buf;    //Buffer for IPC_STAT, IPC_SET 
        unsigned short  *array;  /* Array for GETALL, SETALL */
        struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
    };
    //semid ! this is the number of share memory
    int semid;
    //waiting for fork here
    //left and right = the number of sourses
    void wait_for_1fork(int no)  
    {
        int left = no;
        //system defined struct
        //"first":the current number of pro 
        //"second":resourses -1:wait cannot use;+1:can use
        //"thired":?
        struct sembuf buf[1] =
        {
            {left, -1, 0},
        };
        //semop do wait or signal (p/v)
        //"first": the  number of share memory pro
        //"second":the first point of struct
        //"third":the number of signal to complete
        semop(semid, buf, 1);
    }
    void wait_for_2fork(int no)  
    {
        int right = (no + 1) % 5;
        //system defined struct
        //"first":the current number of pro 
        //"second":resourses -1:wait cannot use;+1:can use
        //"thired":?
        struct sembuf buf[1] =
        {
            {right, -1, 0}
        };
        //semop do wait or signal (p/v)
        //"first": the  number of share memory pro
        //"second":the first point of struct
        //"third":the number of signal to complete
        semop(semid, buf, 1);
    }
    void free_1fork(int no)
    {
        int left = no;
        //system defined struct
        //"first":the current number of pro 
        //"second":resourses -1:wait cannot use;+1:can use
        //"thired":?
        struct sembuf buf[1] = 
        {
            {left, 1, 0},
        };
        semop(semid, buf, 1);
    }
    void free_2fork(int no)
    {
        int right = (no + 1) % 5;
        //system defined struct
        //"first":the current number of pro 
        //"second":resourses -1:wait cannot use;+1:can use
        //"thired":?
        struct sembuf buf[1] = 
        {
            {right, 1, 0}
        };
        semop(semid, buf, 1);
    }
    void philosopere(int num)
    {
        srand(getpid());
        for (; ;)
        {
            //printf("%d is thinking
    ", num);
            printf("33[36m%d is thinking
    33[0m", num);
            if(num!=0)
            sleep(DELAY);
            //printf("%d is hungry
    ", num);
            wait_for_1fork(num);
            //printf("%d pick up left chopsticks
    ", num);
            printf("33[31m%d pick up left chopsticks
    33[0m", num);
            sleep(DELAY);
            sleep(DELAY);
            wait_for_2fork(num);
            //printf("%d pick up right chopsticks
    ", num);
            printf("33[34m%d pick up right chopsticks
    33[0m", num);
            //printf("%d is eating
    ", num);
            sleep(DELAY);
            free_1fork(num);
            //printf("%d return left chopsticks
    ", num);
            printf("33[33m%d return left chopsticks
    33[0m", num);
            sleep(DELAY);
            free_2fork(num);
            //printf("%d return right chopsticks
    ", num);
            printf("33[37m%d return right chopsticks
    33[0m", num);
        }
    }
    int main()
    {
        //use IPC to connect between processes . A new share memory
        //semget() return the number of share memory 
        //new signal key=0 and never change .So not use key
        //"first":use IPC_PRIVATE to share memory between relation processes
        //"second":(size_t)naxSize
        //"third":(int flag)private:666--read and write ; IPC_CREAT creat new memory
        semid = semget(IPC_PRIVATE, 5, IPC_CREAT | 0666);
        if (semid == -1)
            ERR_EXIT("semget");
        union semun su;
        su.val = 1;
        for (int i = 0; i < 5; i++)
        {
            //creat a new object on "semid" 
            //use i to depart 5 processes
            semctl(semid, i, SETVAL, su);
        }
        int no = 0;
        //pid_t (Process ID _ Type) Just like  int
        pid_t pid; 
        for (int i = 1; i < 5; i++)
        {
            //use fork() to make a copy of father process named with child pro
            //father.pid>0 and child.pid=0
            //after for loop will exist a father and five childs(0-4)
            pid = fork();
            if (pid == -1)
                ERR_EXIT("fork");
            if (pid == 0)
            {
                no = i;
                //break the child process loop to run the philosopere
                break;
            }
        }
        philosopere(no);
        return 0;
    }

    right.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/ipc.h>
    #include<sys/msg.h>
    #include<sys/types.h>
    #include<unistd.h>
    #include<errno.h>
    #include<sys/ipc.h>
    #include<sys/sem.h>
    #include<sys/wait.h>
    #define DELAY (rand() % 5 + 1)
    #define ERR_EXIT(m) 
        do { 
            perror(m); 
            exit(EXIT_FAILURE); 
        } while(0)
    
    union semun
    {
        int val;    // Value for SETVAL
        struct semid_ds *buf;    //Buffer for IPC_STAT, IPC_SET 
        unsigned short  *array;  /* Array for GETALL, SETALL */
        struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
    };
    //semid ! this is the number of share memory
    int semid;
    //waiting for fork here
    //left and right = the number of sourses
    void wait_for_2fork(int no)  
    {
        int left = no;
        int right = (no + 1) % 5;
        //system defined struct
        //"first":the current number of pro 
        //"second":resourses -1:wait cannot use;+1:can use
        //"thired":?
        struct sembuf buf[2] =
        {
            {left, -1, 0},
            {right, -1, 0}
        };
        //semop do wait or signal (p/v)
        //"first": the  number of share memory pro
        //"second":the first point of struct
        //"third":the number of signal to complete
        semop(semid, buf, 2);
    }
    void free_2fork(int no)
    {
        int left = no;
        int right = (no + 1) % 5;
        //system defined struct
        //"first":the current number of pro 
        //"second":resourses -1:wait cannot use;+1:can use
        //"thired":?
        struct sembuf buf[2] = 
        {
            {left, 1, 0},
            {right, 1, 0}
        };
        semop(semid, buf, 2);
    }
    void philosopere(int num)
    {
        srand(getpid());
        for (; ;)
        {
            //printf("33[31m Hello
    33[0m");
            //printf("33[36m Hello
    33[0m");
            //printf("\%d is thinking
    ", num);
            printf("33[31m%d is thinking
    33[0m", num);
            sleep(DELAY);
            printf("%d pick up two chopsticks
    ", num);
            printf("33[36m%d pick up two chopsticks
    33[0m", num);
            wait_for_2fork(num);
            //printf("%d is eating
    ", num);
            printf("33[34m%d is eating
    33[0m", num);
            sleep(DELAY);
            free_2fork(num);
        }
    }
    int main()
    {
        //use IPC to connect between processes . A new share memory
        //semget() return the number of share memory 
        //new signal key=0 and never change .So not use key
        //"first":use IPC_PRIVATE to share memory between relation processes
        //"second":(size_t)naxSize
        //"third":(int flag)private:666--read and write ; IPC_CREAT creat new memory
        semid = semget(IPC_PRIVATE, 5, IPC_CREAT | 0666);
        if (semid == -1)
            ERR_EXIT("semget");
        union semun su;
        su.val = 1;
        for (int i = 0; i < 5; i++)
        {
            //creat a new object on "semid" 
            //use i to depart 5 processes
            semctl(semid, i, SETVAL, su);
        }
        int no = 0;
        //pid_t (Process ID _ Type) Just like  int
        pid_t pid; 
        for (int i = 1; i < 5; i++)
        {
            //use fork() to make a copy of father process named with child pro
            //father.pid>0 and child.pid=0
            //after for loop will exist a father and five childs(0-4)
            pid = fork();
            if (pid == -1)
                ERR_EXIT("fork");
            if (pid == 0)
            {
                no = i;
                //break the child process loop to run the philosopere
                break;
            }
        }
        philosopere(no);
        return 0;
    }
  • 相关阅读:
    前言(CSDN也有Markdown了,好开森)
    One usage of recurison: the tower of Hanoi
    使用Android注解来改善代码
    mysql生产环境____主从同步修复案例
    不同类型的指针
    C++ 对象模型
    为什么需要模版成员方法
    理解 traits
    C++ 异常处理
    传const引用代替传值
  • 原文地址:https://www.cnblogs.com/dzzy/p/6256527.html
Copyright © 2020-2023  润新知