有一个资源管理器类。它可以帮助我们访问设备。但是,当然,它应该寻求不同时为两个进程提供对一个设备的访问。
起初我以为我没有任何访问队列。我认为会有像anyFree_devicename()这样的方法,如果有空的话会返回访问句柄,如果没有则返回NULL。但是,由于某些设备的高并发性,我在每个设备上都编写了accessQueue。
现在,当您尝试访问设备时,您的pid(进程ID)会插入到此类accessQueue中,您可以使用特殊方法请求轮到您。
但是,我发现了一个问题:当你在一个命令中需要很少的devicec时,访问队列可以互相阻塞:
Device1 Device2
1 2
2 1
他们两个都会受阻。
inline bool API::Device::Device::ShallIUse(int pid)
{
if (amIFirst(pid)) return 1; // if I'm first I can use it anyway
std::stack<int> tempStorage; // we pass every element acessQ -> Temp
while (acessQueue.front() != pid) // every process
{
//we take process pointer to look into it's queue
API::ProcessManager::Process* proc = API::ProcessManager::TaskManager::me->giveProcess(acessQueue.front());
// list of devices this prosess needs now
std::vector<API::Device::Device*>* dINeed = proc->topCommand()->devINeedPtr();
// an dsee if there any process
for (int i = 0; i < (dINeed->size() - 1); i++)
{
if (!dINeed[i]->mIFirst())
{
while ( ! tempStorage.empty())
{
acessQueue.push(tempStorage.top());
tempStorage.pop();
}
return 0;
}
}
tempStorage.push(acessQueue.front());
acessQueue.pop();
}
return 1;
我之后写过这样的算法,但是:
它破坏了所有基于图层的架构
现在看来工作有误。
那太疯狂了!我们只是查看几乎所有进程中的所有命令,并尝试在访问队列上推送一些命令。它工作得很慢。
答案 0 :(得分:2)
您的访问队列正在创建所谓的死锁。多个客户端永远被阻止,因为他们试图以不同的顺序获取同一组资源的所有权。
您可以通过为所有资源分配唯一值来避免此问题。让客户端向资源管理器提交所需资源的列表。资源管理器的获取方法将按资源编号对列表进行排序,然后尝试按顺序分配该组资源。
这将强制执行所有收购的特定订单,您将永远无法陷入僵局。
当然,任何给定的客户端都会阻塞,直到它需要的所有资源都可用。