操作系统课程设计--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;
}
原文地址:https://www.cnblogs.com/dzzy/p/6256527.html