1

试图通过创建一个门卫来解决哲学家就餐问题,只允许 4 位哲学家同时用餐,计划为此使用信号量,但网络上关于它们的资料有限,我不知道如何增加信号量的价值一旦发出信号。

#define INITIAL_COUNT 1 
#define MAX_COUNT 4

主要的()

philo.doorSemaphore = CreateSemaphore(
    NULL,           //default security attributes
    INITIAL_COUNT,  //initial count
    MAX_COUNT,  //maximum count

    NULL);

while (philo.not_dead == true)
{
    int num_philosophers = 5;
    for (int i = 0; i < 5; i++)
    {
        philo.mythread[i] =  thread (philosophersFunction, i);      //init 5 threads calling philofunction each loop
        philo.mythread[i].join();                                   //join thread to current thread each loop
    }
    sleep_for(milliseconds(500));
    system("cls");
}

等待()

void Philosophers::waiting(int current)
{

dWaitResult = WaitForSingleObject(doorSemaphore, 0L);
//waitResult = WaitForSingleObject(semaphores, 0L);

switch (dWaitResult)
{
case WAIT_OBJECT_0:
    p[current] = hungry;
    ReleaseSemaphore(doorSemaphore, 1, NULL);
    break;
case WAIT_TIMEOUT:
    hunger[current] ++;
    counter[current] ++;
case WAIT_FAILED :
    break;

    CloseHandle(doorSemaphore);
    }
}
4

1 回答 1

1

Dining Philosophers Rebooted使用现代 C++std::threadstd::mutex. 完整的源代码可在链接中找到。

此代码通过将每个分叉表示为std::mutex. 然后诀窍是如何同时锁定两个互斥锁而不会导致死锁。C++11/14 专门为此目的提供了一个函数:

template <class L1, class L2, class... L3>
    void lock(L1&, L2&, L3&...);

上面的论文探讨了std::lock2 个互斥体和 3 个互斥体情况的几种可能实现,并确定了一种算法,它永远不会比任何其他算法差(而且通常要好得多)。

最佳实现(根据本文)实际上是libc++使用的算法。

这是本文Philosopher::eat()中“二维”案例的功能:

void
Philosopher::eat()
{
    using Lock = std::unique_lock<std::mutex>;
    Lock first;
    Lock second;
    if (flip_coin())
    {
        first = Lock(left_fork_, std::defer_lock);
        second = Lock(right_fork_, std::defer_lock);
    }
    else
    {
        first = Lock(right_fork_, std::defer_lock);
        second = Lock(left_fork_, std::defer_lock);
    }
    auto d = get_eat_duration();
    ::lock(first, second);
    auto end = std::chrono::steady_clock::now() + d;
    while (std::chrono::steady_clock::now() < end)
        ;
    eat_time_ += d;
}

仅出于演示目的,Philosopher随机选择左手和右手握住哪个叉子。解决问题不需要这种随机性。该功能可以简化为以下内容并且仍然是正确的:

void
Philosopher::eat()
{
    using Lock = std::unique_lock<std::mutex>;
    Lock first { left_fork_, std::defer_lock};
    Lock second{right_fork_, std::defer_lock};
    auto d = get_eat_duration();
    ::lock(first, second);
    auto end = std::chrono::steady_clock::now() + d;
    while (std::chrono::steady_clock::now() < end)
        ;
    eat_time_ += d;
}

在实际代码中,调用::lock应该是std::lock,但这段代码正在尝试几种实现,std::lock而不会侵入性地更改 std::lib。

于 2016-04-22T20:07:15.043 回答