与此读者代码类似的模式很常见:进入某个部分的第一个线程锁定信号量(或队列),最后一个线程解锁它。 事实上,它是如此常见,我们应该给它一个名称,并将其包装在一个对象中。
模式的名称是Lightswitch,类似于进入房间的第一个人打开灯(锁定互斥锁)的模式,最后一个人将其关闭(解锁互斥锁)。 这是Lightswitch的类定义:
typedef struct _LightSwitch
{
int Counter;
osSemaphoreId_t Mutex;
void (*Init)(struct _LightSwitch* light);
void (*Lock)(struct _LightSwitch* light, osSemaphoreId_t sem);
void (*Unlock)(struct _LightSwitch* light, osSemaphoreId_t sem);
}LightSwitch;
void Init(LightSwitch* light)
{
light->Counter = 0;
light->Mutex = osSemaphoreNew(1, 1, NULL);
}
void Lock(LightSwitch* light, osSemaphoreId_t sem)
{
osSemaphoreAcquire(light->Mutex, osWaitForever);
{
(light->Counter)++;
if(light->Counter == 1)
{
osSemaphoreAcquire(sem, osWaitForever);
}
}
osSemaphoreRelease(light->Mutex);
}
void Unlock(LightSwitch* light, osSemaphoreId_t sem)
{
osSemaphoreAcquire(light->Mutex, osWaitForever);
{
(light->Counter)--;
if(light->Counter == 0)
{
osSemaphoreRelease(sem);
}
}
osSemaphoreRelease(light->Mutex);
}
void init_light(LightSwitch* light)
{
light->Init = Init;
light->Lock = Lock;
light->Unlock = Unlock;
}
初始化
osSemaphoreId_t sem_mutex;
sem_mutex = osSemaphoreNew(1, 1, NULL);
LightSwitch light;
init_light(&light);
light.Init(&light);
读者线程
while(1)
{
light.Lock(&light, sem_roomEmpty);
critical_reader();
light.Unlock(&light, sem_roomEmpty);
}