哲学家进餐问题 - 只有 2 个线程有效

Posted

技术标签:

【中文标题】哲学家进餐问题 - 只有 2 个线程有效【英文标题】:Dining philosophers problem - only 2 thread worked 【发布时间】:2020-05-05 23:01:09 【问题描述】:

我正在尝试解决dining philosophers problem。

就我而言,每个哲学家都应该吃 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
每位哲学家必须交替思考和进食。然而,哲学家只有在左右叉子都有的情况下才能吃意大利面。每个叉子只能由一个哲学家持有,因此只有在另一位哲学家不使用叉子时,哲学家才能使用叉子。

【问题讨论】:

想想如果您的TryEnterCriticalSection 调用之一失败会发生什么,以及在什么情况下会发生这种情况。 【参考方案1】:

想想这里的逻辑

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

如果TryEnterCriticalSection(&amp;a) 成功而TryEnterCriticalSection(&amp;b) 失败会发生什么; CS a 永远保持进入状态。

它应该看起来像

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

【讨论】:

以上是关于哲学家进餐问题 - 只有 2 个线程有效的主要内容,如果未能解决你的问题,请参考以下文章

哲学家进餐问题

哲学家进餐

哲学家进餐问题

经典进程的同步问题之——哲学家进餐

(考研)哲学家进餐问题(附代码)

Java总结—实现Runnable接口创建线程,线程安全同步,死锁(哲学家进餐问题),读写锁