uC/OSIII互斥信号量思考题及答案
时间: 2023-07-29 15:06:22 浏览: 55
以下是一个uC/OSIII互斥信号量的思考题及答案:
思考题:假设有两个任务TaskA和TaskB,它们都需要对共享资源进行访问。为了保证数据的一致性,需要使用互斥信号量来进行同步。以下是TaskA和TaskB的代码实现,请问这样实现是否正确?如果不正确,请指出问题所在,并给出修改意见。
```
OS_MUTEX mutex;
void TaskA(void *p_arg) {
while (1) {
OSSemWait(&mutex, 0, &err); // 获取互斥信号量
// 访问共享资源的代码
OSSemPost(&mutex, &err); // 释放互斥信号量
}
}
void TaskB(void *p_arg) {
while (1) {
OSSemWait(&mutex, 0, &err); // 获取互斥信号量
// 访问共享资源的代码
OSSemPost(&mutex, &err); // 释放互斥信号量
}
}
```
答案:以上代码存在问题,问题在于互斥信号量的使用不是原子操作。假设TaskA获取了互斥信号量,此时TaskB也尝试获取互斥信号量,但由于TaskA还未释放互斥信号量,TaskB将被阻塞。但当TaskA释放互斥信号量后,TaskB并不会立即执行,而是需要等待调度器重新进行调度。在这段时间内,TaskA有可能再次获取互斥信号量,这样就会导致互斥信号量的使用出现问题。
为了解决这个问题,可以将获取互斥信号量和访问共享资源的代码放在一个临界区内,这样就能保证它们的原子性。修改后的代码如下:
```
OS_MUTEX mutex;
void TaskA(void *p_arg) {
while (1) {
OSMutexPend(&mutex, 0, &err); // 进入临界区
// 访问共享资源的代码
OSMutexPost(&mutex, &err); // 离开临界区
}
}
void TaskB(void *p_arg) {
while (1) {
OSMutexPend(&mutex, 0, &err); // 进入临界区
// 访问共享资源的代码
OSMutexPost(&mutex, &err); // 离开临界区
}
}
```