我不是开发人员,我只是想通过尝试让我的工作场所更加自主来进行编程。 我目前正在尝试获得具有所有不同优先级(0:最高8:最低)的9个线程,以使用相同的UART端口。
由于我必须发送紧急请求,我将创建一个锁,允许最高优先级的线程首先在资源上。
我还必须让receive_data IRQ线程在UART端口发生时尽快(或者硬件UART缓冲区的长度为500字节)。
我一直在环顾四周,如果我需要更多优先级/线程(或者至少需要相当多的编码),使用嵌套互斥锁会阻止我使代码发展。
我已经阅读了这个问题:How to give priority to privileged thread in mutex locking?,第二个答案看起来像我想要的......但我不明白如何实施这个过程。
由于问题有点陈旧,还有另一种方法可以做我想要的吗? 如果没有,我可以获得更具可读性的版本(木工)吗?
问题:如何保护对UART读写器的访问&根据优先级给予线程优先权?
注意:
线程当前正在读取一个FIFO,并且当fifo为空时正在休眠,并且当某些内容放入各自的fifo时开始。
然后,线程以可由硬件解释并通过UART发送的格式处理命令/数据。
我尝试这样做,因为我意识到有时紧急命令在我使用单个线程并且fifo被大量填充之前在处理之前等待~1或更多。
另外,对不起,如果我的英语给你起了疙瘩。
答案 0 :(得分:1)
如评论中所述,这是一项复杂的任务。
一种方法是创建一个类似这样的类:
class UART_access_manager
{
typedef std::multimap<int, dispatch_semaphore_t> priority_map_t;
public:
UART_access_manager();
~UART_access_manager();
void access_manager(unsigned int prio, dispatch_semaphore_t pSem);
private:
void amInext(unsigned int prio);
void process_priority(unsigned int prio);
void priority_locker(unsigned int prio);
void priority_unlocker(unsigned int prio);
int count;
std::mutex data_mtx, priority_0_mtx, mtx;
priority_map_t priority_map;
};
请注意我在OSX上构建测试并且无法使用未命名的信号量,我没有检查其他操作系统上是否有可用的调度(可能不是苹果库)。
UART_access_manager::UART_access_manager()
{
}
UART_access_manager::~UART_access_manager()
{
}
/*********************************************************************
*
* Function: void UART_access_manager::access_manager(unsigned
int prio, dispatch_semaphore_t pSem)
*
* Description: add an UART access request to the queue based on priority & start process based on type
*
* Notes: 0 is highest
*
* Returns: none
*
*********************************************************************/
void UART_access_manager::access_manager(unsigned int prio, dispatch_semaphore_t pSem)//, add parameters at will
{
int counter = 1; //debug only
while (counter) //should check for termination criteria
{
//check if something was pushed on the file descriptor
if( counter == 10) //add run condition
{
counter = 0; //debug
priority_locker(prio);
priority_map_t::iterator it = priority_map.insert(std::pair<int, dispatch_semaphore_t>(prio, pSem) );
printf("\n thread with priority %d added to queue(size %lu)", prio, priority_map.size());
amInext(prio);
priority_unlocker(prio);
while(dispatch_semaphore_wait(pSem, DISPATCH_TIME_NOW) != 0){};
priority_locker(prio);
// do the actual job
process_priority(prio);
// done, remove yourself
priority_map.erase(it);
if( ! priority_map.empty() )
{
// let next guy run:
dispatch_semaphore_signal((priority_map.begin()->second));
}
priority_unlocker(prio);
}
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(50)); //test purpose only
counter++;
}
}
}
/*********************************************************************
*
* Function: void UART_access_manager::amInext(unsigned int prio)
*
* Description: check if current priority has to run next or not
*
* Notes: 0 is highest
*
* Returns: none
*
*********************************************************************/
void UART_access_manager::amInext(unsigned int prio)
{
if(priority_map.begin()->first == prio) dispatch_semaphore_signal(priority_map.begin()->second);
}
/*********************************************************************
*
* Function: void UART_access_manager::process_priority(unsigned
int prio)
*
* Description: TODO
*********************************************************************/
void UART_access_manager::process_priority(unsigned int prio)
{
printf("\n Priority_%d running \n",prio);
//TODO
}
/*********************************************************************
*
* Function: void UART_access_manager::priority_locker(unsigned
int prio)
*
* Description: lock mutex in a way to guarantee priority event
to
* get the fastest lock possible
*
* Notes: 0 is highest
******************************************************************/
void UART_access_manager::priority_locker(unsigned int prio)
{
//Low-priority threads: lock mtx, lock priority_0_mtx, lock data_mtx,
unlock priority_0_mtx,
//High-priority thread: lock priority_0_mtx, lock data_mtx, unlock
priority_0_mtx,
//this will insure that max priority level get privileged access to
the data
if(!prio)
{
priority_0_mtx.lock();
data_mtx.lock();
priority_0_mtx.unlock();
}
else
{
mtx.lock();
priority_0_mtx.lock();
data_mtx.lock();
priority_0_mtx.unlock();
}
}
/*********************************************************************
*
* Function: void
UART_access_manager::priority_unlocker(unsigned int prio)
*
* Description: unlock mtx based on the mutex locked by the
priority level
*
* Notes: 0 is highest
*
* Returns: none
*
*********************************************************************/
void UART_access_manager::priority_unlocker(unsigned int prio)
{
if(!prio)
{
data_mtx.unlock();
}
else
{
mtx.unlock();
data_mtx.unlock();
}
}
代码很容易理解,并且不会做任何事情,你进展顺利,看作是一项任务,如果你有任何问题不要犹豫评论,我会回复
(HS:你想做什么?)
您将学到的东西: 的std :: multimap中 的std ::互斥 信号灯 课程