参考https://blog.csdn.net/booksyhay/article/details/82762278
根据应用程序,为写者提供更高的优先级可能是个好主意。 例如,如果写者要对数据结构进行更新,而这种更新又是时序要求很严格的,则最好在写者有机会继续之前,将能查看旧数据的读者的数量控制到最小。
初始化
osSemaphoreId_t sem_noReaders;
sem_noReaders = osSemaphoreNew(1, 1, NULL);
osSemaphoreId_t sem_noWriters;
sem_noWriters = osSemaphoreNew(1, 1, NULL);
LightSwitch readSwitch;
init_light(&readSwitch);
readSwitch.Init(&readSwitch);
LightSwitch WriteSwitch;
init_light(&WriteSwitch);
WriteSwitch.Init(&WriteSwitch);
读者线程
如果一个读者在临界区,它拥有noWriters,但它不包含noReaders。 因此,如果写者到达它可以锁定noReaders,这将导致后续读者排队。
当最后一个读者退出时,它会发出noWriters信号,允许任何排队的写者继续运行。
while(1)
{
osSemaphoreAcquire(sem_noReaders, osWaitForever);
{
readSwitch.Lock(&readSwitch, sem_noWriters);
}
osSemaphoreRelease(sem_noReaders);
printf("--read\r\n");
readSwitch.Unlock(&readSwitch, sem_noWriters);
osDelay(250);
}
写者线程
当写者在临界区时,它同时拥有noReaders和noWriters。 这具有(相对明显的)效果,即确保在临界区没有读者并且也没有其他写者。 此外,writeSwitch具有允许多个写者在noWriters上排队的(不太明显的)效果,但是当它们存在时保持noReaders被锁定。 因此,许多写者可以通过临界区而无需发出noReaders信号。 只有当最后一位写者退出时,读者才能进入。
当然,这种解决方案的一个缺点是,现在读者可能会饿死(或至少面临长时间的延迟)。对于某些应用程序来说,最好的办法是获得具有可预测周转时间的往期的数据。
while(1)
{
WriteSwitch.Lock(&WriteSwitch, sem_noReaders);
{
osSemaphoreAcquire(sem_noWriters, osWaitForever);
{
printf("--write\r\n");
}
osSemaphoreRelease(sem_noWriters);
}
osDelay(1000);
WriteSwitch.Unlock(&WriteSwitch, sem_noReaders);
osDelay(1000);
}
结论:
来源:CSDN
作者:小C菜鸟
链接:https://blog.csdn.net/C_cai_niao/article/details/104009540