做项目多线程执行的时候,想在一定时间内,多个线程需要占用同一资源并需要反复使用此资源同时让最先占用的线程最先使用资源完成的情况下,通过这个控制线程运行的优先级顺序,于是设计了一个优先级锁的东西,继承MFC的CMutex实现。(我这里是通过与线程绑定的数字大小决定优先级顺序。)
//所有优先级顺序信息
//@key:线程优先级
//@value:线程ID
std::multiset<std::pair<int,DWORD>,std::greater<std::pair<int,DWORD>>> _lootqueue_;
//存储所有优先级
//@key:线程ID
//@value:等级
std::map<DWORD,int> _prioritymap_;
//对_lootqueue_操作时的保护锁
CMutex _mutex_;
1.Lock函数
BOOL CPriorityMutex::Lock(DWORD dwTimeOut)
{
//通过multiset(也可以使用其他容器并进行排序)插入线程ID以及优先级
//我这里默认第一次Lock所在线程优先级最低
auto nTheadId = ::GetCurrentThreadId();
_mutex_.Lock();
if (_prioritymap_.count(nTheadId)==0)
{
_prioritymap_[nTheadId] = 0;
}
auto temp_queue = _lootqueue_;//临时对象
//当前线程优先级添加至竞争序列
_lootqueue_.insert(std::pair<int,DWORD>(_prioritymap_[nTheadId],nTheadId));
_mutex_.Unlock();
int nTimes = 0;
while(TRUE)
{
//如果一定时间内没有竞争对象 则直接退出Lock和竞争序列
if (dwTimeOut!=INFINITE)
{
if (dwTimeOut<=nTimes)
{
_mutex_.Lock();
_lootqueue_ = temp_queue;
_mutex_.Unlock();
return FALSE;
}
}
_mutex_.Lock();
BOOL rt = _lootqueue_.begin()->second == nTheadId;
if (rt)
{
//执行过的优先级提升 线程内需要再次使用时竞争优先
_prioritymap_[nTheadId]++;
_lootqueue_.erase(_lootqueue_.begin());
_lootqueue_.insert(std::pair<int,DWORD> (_prioritymap_[nTheadId],nTheadId));
rt = CMutex::Lock(dwTimeOut);
_mutex_.Unlock();
return rt;
}
_mutex_.Unlock();
Sleep(1);
nTimes++;
}
}
1.Unlock函数
BOOL CPriorityMutex::Unlock()
{
BOOL rt = CMutex::Unlock();
if (rt)
{
_mutex_.Lock();
_lootqueue_.erase(_lootqueue_.begin());
_mutex_.Unlock();
Sleep(10);
return TRUE;
}
Sleep(10);
return FALSE;
}