Столовая проблема философов - только 2 темы работали - PullRequest
2 голосов
/ 20 января 2020

Я пытаюсь решить проблему столовых философов .

В моем случае каждый философ должен есть 1 000 000 раз. Проблема в том, что кажется, что «1» и «3» закончили есть. Я использую потоки с блокировкой критического раздела, вот мой код:

CRITICAL_SECTION ghCARITICALSection1;
CRITICAL_SECTION ghCARITICALSection2;
CRITICAL_SECTION ghCARITICALSection3;
CRITICAL_SECTION ghCARITICALSection4;
CRITICAL_SECTION ghCARITICALSection5;
DWORD WINAPI func(int* phiphilosopher)
{
    if (1 == *phiphilosopher && TryEnterCriticalSection(&ghCARITICALSection1) && TryEnterCriticalSection(&ghCARITICALSection2))
    {
        std::cout << "1 is eating...\n";
        for (int i = 0; i < 1000000; i++)
        {
            i = i;
        }
        LeaveCriticalSection(&ghCARITICALSection1);
        LeaveCriticalSection(&ghCARITICALSection2);
    }
    if (2 == *phiphilosopher && TryEnterCriticalSection(&ghCARITICALSection2) && TryEnterCriticalSection(&ghCARITICALSection3))
    {
        std::cout << "2 is eating...\n";
        for (int i = 0; i < 1000000; i++)
        {
        }
        LeaveCriticalSection(&ghCARITICALSection2);
        LeaveCriticalSection(&ghCARITICALSection3);
    }
    if (3 == *phiphilosopher && TryEnterCriticalSection(&ghCARITICALSection3) && TryEnterCriticalSection(&ghCARITICALSection4))
    {
        std::cout << "3 is eating...\n";
        for (int i = 0; i < 1000000; i++)
        {
        }
        LeaveCriticalSection(&ghCARITICALSection3);
        LeaveCriticalSection(&ghCARITICALSection4);
    }
    //...also for 4,5
    return 0;
}
    int philosopher1 = 1;
    int* philosopher1ptr = &philosopher1;
    int philosopher2 = 2;
    int* philosopher2ptr = &philosopher2;
    //...Also for philosopher 3,4,5

    InitializeCriticalSection(&ghCARITICALSection1);
    InitializeCriticalSection(&ghCARITICALSection2);
//...aslo for ghCARITICALSection 3,4,5

    HANDLE WINAPI th1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, philosopher1ptr, 0, NULL);
    HANDLE WINAPI th2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, philosopher2ptr, 0, NULL);
////...aslo for th3,4,5
    WaitForSingleObject(th1, INFINITE);
    WaitForSingleObject(th2, INFINITE);
    //...also for th3,4,5
  • Каждый философ должен попеременно думать и есть. Однако философ может есть спагетти только тогда, когда у него есть как левая, так и правая вилка. Каждую вилку может держать только один философ, и поэтому философ может использовать вилку, только если она не используется другим философом.

1 Ответ

1 голос
/ 20 января 2020

Подумайте о логике c здесь

    if (TryEnterCriticalSection(&a) && TryEnterCriticalSection(&b)) {
        // . . .
        LeaveCriticalSection(&a);
        LeaveCriticalSection(&b);
    }

Что произойдет, если TryEnterCriticalSection(&a) будет успешным, а TryEnterCriticalSection(&b) - неудачным; CS a остается во введенном состоянии навсегда.

Это должно выглядеть примерно так:

    if (TryEnterCriticalSection(&a)) {
        if (TryEnterCriticalSection(&b)) {
            // . . .
            LeaveCriticalSection(&b);
        }
        LeaveCriticalSection(&a);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...