#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;
}
层次锁示范解决哲学家就餐问题
最新推荐文章于 2022-10-24 14:29:55 发布