哲学家就餐模型




解决方案1:

#include <stdio.h>
#include <windows.h>
#include <iostream>

using namespace std;

CRITICAL_SECTION  cs;
CRITICAL_SECTION ChopStick[5];
int state[5];

DWORD WINAPI Philosopher(LPVOID pArg)
{
    int c=(int)pArg;
    while(true)
    {

        state[c]=0;
        Sleep(3000);
        if(c%2==1)
        {
            state[c]=1; // 等右
            EnterCriticalSection(&ChopStick[(c+1)%5]);
            state[c]=2; // 等左
            EnterCriticalSection(&ChopStick[c%5]  );
        }
        else
        {
            state[c]=2; // 等左
            EnterCriticalSection(&ChopStick[c%5]  );
            state[c]=1; // 等右
            EnterCriticalSection(&ChopStick[(c+1)%5]);
        }


        state[c]=3;
        Sleep(2000);

        LeaveCriticalSection(&ChopStick[c%5]);
        LeaveCriticalSection(&ChopStick[(c+1)%5]);
    }
    return 0;
}

void printf()
{
    cout<<endl;
    cout<<endl;
    for(int i=0;i<5;i++)
        printf("\t哲学家%d",i);
    cout<<endl;
    for(int i=0;i<5;i++)
    {
        if(state[i]==0)
            printf("\t思考");
        else if(state[i]==1)
            printf("\t等右");
        else if(state[i]==2)
            printf("\t等左");
        else if(state[i]==3)
            printf("\t进餐");

    }

}

int main()
{
    cout<<"哲学家进餐问题"<<endl<<"    规则:五个哲学家,他们交替地进行思考和进餐。";
    cout<<"他们分别坐在位于一个圆形餐桌周围的五把椅子上,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。";
    cout<<"当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起和他相邻的两根筷子进行进餐,";
    cout<<"但他很可能仅拿到一根,此时旁边的另一根正在他邻居的手中,那么他必须等待。";
    cout<<"只有他同时拿到两根筷子时他才能开始进餐。";
    cout<<"完成进餐后,他将两根筷子分别放回原位,然后再次开始思考。本例哲学家每隔3秒进餐一次,每次进餐时间为2秒。";


    system("pause");


    for(int i=0;i<5;i++)
        InitializeCriticalSection(&ChopStick[i]);
    HANDLE hThread[5];


    for(int i=0;i<5;i++)
        hThread[i] = CreateThread(NULL, 0,  Philosopher, (LPVOID)i, 0, NULL );

    while(true)
    {
        printf();
        Sleep(1000);

    }

    system("pause");
    return 0;
}



解决方案2:

#include <stdio.h>
#include <windows.h>
#include <iostream>

using namespace std;

#define N 5
#define LEFT (i + N - 1) % N
#define RIGHT (i + 1) % N
#define THINKING 0
#define HUNGRY 1
#define EATING 2

int state[N];
HANDLE hMutex = NULL;
HANDLE semArr[N] = {NULL};

void test(int i)
{
    if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING)
    {
        state[i] = EATING;
        Sleep(1000);
        ReleaseSemaphore(semArr[i], 1, NULL);
    }
}

void take_forks(int i)
{
    WaitForSingleObject(hMutex, INFINITE);
    state[i] = HUNGRY;
    Sleep(1000);
    test(i);
    ReleaseMutex(hMutex);

    WaitForSingleObject(semArr[i], INFINITE);
}

void put_forks(int i)
{
    WaitForSingleObject(hMutex, INFINITE);
    state[i] = THINKING;
    Sleep(1000);
    test(LEFT);
    test(RIGHT);
    ReleaseMutex(hMutex);
}

DWORD WINAPI Philosopher(LPVOID pArg)
{
    int c=(int)pArg;
    while(true)
    {
        take_forks(c);

        put_forks(c);
    }
    return 0;
}

void printf()
{
    cout<<endl;
    cout<<endl;
    for(int i=0;i<5;i++)
        printf("\t哲学家%d",i);
    cout<<endl;
    for(int i=0;i<5;i++)
    {
        if(state[i]==THINKING)
            printf("\t思考");
        else if(state[i]==HUNGRY)
            printf("\t等待");
        else if(state[i]==EATING)
            printf("\t进餐");

    }

}

int main()
{
    cout<<"哲学家进餐问题"<<endl<<"    规则:五个哲学家,他们交替地进行思考和进餐。";
    cout<<"他们分别坐在位于一个圆形餐桌周围的五把椅子上,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。";
    cout<<"当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起和他相邻的两根筷子进行进餐,";
    cout<<"但他很可能仅拿到一根,此时旁边的另一根正在他邻居的手中,那么他必须等待。";
    cout<<"只有他同时拿到两根筷子时他才能开始进餐。";
    cout<<"完成进餐后,他将两根筷子分别放回原位,然后再次开始思考。本例哲学家每隔3秒进餐一次,每次进餐时间为2秒。";


    system("pause");


    for(int i=0;i<5;i++)
    {
        semArr[i] = CreateSemaphore(NULL, 0, 1, NULL);
    }

    HANDLE hThread[5];
    for(int i=0;i<5;i++)
    {
        hThread[i] = CreateThread(NULL, 0,  Philosopher, (LPVOID)i, 0, NULL );
    }

    while(true)
    {
        printf();
        Sleep(1000);
    }

    system("pause");
    return 0;
}



解决方案3:


#include <stdio.h>
#include <windows.h>
#include <iostream>

using namespace std;

#define N 5
#define LEFT (i + N - 1) % N
#define RIGHT (i + 1) % N
#define THINKING 0
#define HUNGRY 1
#define EATING 2

int state[N];
HANDLE hMutex = NULL;
HANDLE semArr[N] = {NULL};

HANDLE sem = NULL;

void test(int i)
{
    if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING)
    {
        state[i] = EATING;
        Sleep(1000);
        //ReleaseSemaphore(semArr[i], 1, NULL);
    }
}

void take_forks(int i)
{
   // WaitForSingleObject(hMutex, INFINITE);
    state[i] = HUNGRY;
    Sleep(1000);
    test(i);
    //ReleaseMutex(hMutex);

    //WaitForSingleObject(semArr[i], INFINITE);
}

void put_forks(int i)
{
    //WaitForSingleObject(hMutex, INFINITE);
    state[i] = THINKING;
    Sleep(1000);
    test(LEFT);
    test(RIGHT);
    //ReleaseMutex(hMutex);
}

DWORD WINAPI Philosopher(LPVOID pArg)
{
    int c=(int)pArg;
    while(true)
    {
        WaitForSingleObject(sem, INFINITE);
        take_forks(c);
        put_forks(c);
    }
    return 0;
}

void printf()
{
    cout<<endl;
    cout<<endl;
    for(int i=0;i<5;i++)
        printf("\t哲学家%d",i);
    cout<<endl;
    for(int i=0;i<5;i++)
    {
        if(state[i]==THINKING)
            printf("\t思考");
        else if(state[i]==HUNGRY)
            printf("\t等待");
        else if(state[i]==EATING)
            printf("\t进餐");

    }

}

int main()
{
    cout<<"哲学家进餐问题"<<endl<<"    规则:五个哲学家,他们交替地进行思考和进餐。";
    cout<<"他们分别坐在位于一个圆形餐桌周围的五把椅子上,餐桌上共有五根筷子,分别摆放在每两个相邻座位的中间。";
    cout<<"当哲学家思考时,他不与其他人交谈。当哲学家饥饿时,他将拿起和他相邻的两根筷子进行进餐,";
    cout<<"但他很可能仅拿到一根,此时旁边的另一根正在他邻居的手中,那么他必须等待。";
    cout<<"只有他同时拿到两根筷子时他才能开始进餐。";
    cout<<"完成进餐后,他将两根筷子分别放回原位,然后再次开始思考。本例哲学家每隔3秒进餐一次,每次进餐时间为2秒。";


    system("pause");


    for(int i=0;i<5;i++)
    {
        semArr[i] = CreateSemaphore(NULL, 0, 1, NULL);
    }

    sem = CreateSemaphore(NULL, 0, 4, NULL);

    HANDLE hThread[5];
    for(int i=0;i<5;i++)
    {
        hThread[i] = CreateThread(NULL, 0,  Philosopher, (LPVOID)i, 0, NULL );
    }

    while(true)
    {
        printf();
        Sleep(1000);
        ReleaseSemaphore(sem, 4, NULL);
    }

    system("pause");
    return 0;
}















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值