层次锁示范解决哲学家就餐问题

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

#include <mutex>
#include <stdexcept>
#include <climits>
#include <iostream>
#include <thread>
#include <vector>
using namespace std;

class hierarchical_mutex
{
    std::mutex internal_mutex;
    unsigned long const hierarchy_value;
    unsigned long previous_hierarchy_value;
    static thread_local unsigned long this_thread_hierarchy_value;

    void check_for_hierarchy_violation()
    {
        if (this_thread_hierarchy_value <= hierarchy_value)
        {
            throw std::logic_error("mutex hierarchy violated");
        }
    }
    void update_hierarchy_value()
    {
        previous_hierarchy_value = this_thread_hierarchy_value;
        this_thread_hierarchy_value = hierarchy_value;
    }

public:
    explicit hierarchical_mutex(unsigned long value) : hierarchy_value(value),
                                                       previous_hierarchy_value(0)
    {
    }
    void lock()
    {
        check_for_hierarchy_violation();
        internal_mutex.lock();
        update_hierarchy_value();
    }
    void unlock()
    {
        this_thread_hierarchy_value = previous_hierarchy_value;
        internal_mutex.unlock();
    }
    bool try_lock()
    {
        check_for_hierarchy_violation();
        if (!internal_mutex.try_lock())
            return false;
        update_hierarchy_value();
        return true;
    }
};
thread_local unsigned long hierarchical_mutex::this_thread_hierarchy_value(ULONG_MAX);

vector<hierarchical_mutex *> mutexs;
vector<thread *> threads;

//延迟函数
void delay(int len)
{
    int i = rand() % len;
    int x;
    while (i > 0)
    {
        x = rand() % len;
        while (x > 0)
        {
            x--;
        }
        i--;
    }
}

// 哲学家拿筷子
// 异常出现的情况是先拿了低级锁  在拿高级锁  此时需要释放低级锁
void get_mutux(int num)
{
    while (1)
    {
        int number = 0;
        try
        {
            if (rand() % 2 == 0)
            {
                number = num;
                delay(50000);
                // printf("第%d号哲学家开始拿%d号筷子\n", num, num);
                mutexs[num]->lock();
                printf("第%d号哲学家拿到了%d号筷子\n", num, num);

                number = (num + 1) % 5;
                delay(50000);

                // printf("第%d号哲学家开始拿%d号筷子\n", num, number);
                mutexs[number]->lock();
                printf("第%d号哲学家拿到了%d号筷子\n", num, number);
                
                printf("第%d号哲学家吃到饭了\n", num);
            }
            else
            {
                number = (num + 1) % 5;
                delay(50000);
                // printf("第%d号哲学家开始拿%d号筷子\n", num, number);
                mutexs[number]->lock();
                printf("第%d号哲学家拿到了%d号筷子\n", num, number);


                number = num;
                delay(50000);
                // printf("第%d号哲学家开始拿%d号筷子\n", num, num);
                mutexs[num]->lock();
                printf("第%d号哲学家拿到了%d号筷子\n", num, num);

                printf("第%d号哲学家吃到饭了\n", num);
                delay(1215752191);
            }
        }
        catch (const std::exception &e)
        {
            printf("第%d号哲学家拿%d号筷子失败\n", num, number);
            if (num == number)
            {
                number = (num + 1) % 5;
                mutexs[number]->unlock();
                printf("第%d号哲学家释放了%d号筷子\n", num, number);
            }
            else
            {
                mutexs[num]->unlock();
                printf("第%d号哲学家释放了%d号筷子\n", num, num);
            }
        }
    }
}

int main(int argc, char **argv)
{
    srand(time(NULL));

    // 生成5个层级不同的筷子
    for (size_t i = 0; i < 5; i++)
    {
        mutexs.emplace_back(move(new hierarchical_mutex(i * 100)));
    }

    // 生成5个哲学家
    for (size_t i = 0; i < 5; i++)
    {
        threads.emplace_back(move(new thread(get_mutux, i)));
    }

    for (size_t i = 0; i < 5; i++)
    {
        threads[i]->join();
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值