请任何人都可以帮助我解决这个问题。是否可以让 2 个不同的任务创建 2 个不同的信号量来保护 VxWorks 中的相同关键资源?
2 回答
我想你在这里遗漏了一些东西,
在 vxWorks 中,所有任务共享相同的内存空间,因此,您必须使用 Mutex 保护任务之间的全局数据。
这个想法是只使用一个 Mutex(它的 sem_id 对于所有想要使用它的任务都是众所周知的)。
您可以使用一个 Mutex 保护数据(使用同一个 Mutex 的任务数量没有限制)。
如果您确实想在 vxWorks 中的 2 个任务之间访问相同的内存空间,最好的方法是:创建访问函数
int access_func(void)
{
static SEM_ID sem_id=0;
if(sem_id == 0)
{
/* create mutex semaphore \u2013 semMCreate(\u2026) */
}
return_code=semTake(sem_id, time_out);
if(return_code != 0) return errno;
/* read or write to or from global memory */
semGive(sem_id);
}
笔记:
semMCreate中有几个选项,semTake中有几个选项
您可以在系统初始化时创建互斥锁(推荐)。
如果没有读到mutex,sem_id还是0,semTake返回ERROR(可以查看返回码和系统errno)
这应该包含在 vxWorks 文档中。
通常,您应该将信号量的创建与信号量的使用分离。
/**Initialization Code**/
SEM_ID semM;
semM = semMCreate (...);
...
taskSpawn(task1...);
taskSpawn(task2...);
...
/* Task 1 code */
void task1() {
...
semTake (semM, WAIT_FOREVER);
...<Task 1 critical section>
semGive (semM);
...
}
/* Task 2 code */
void task2() {
...
semTake (semM, WAIT_FOREVER);
...< Task 2 critical section>
semGive (semM);
...
}
在这种情况下,semM 是两个任务都可用的全局变量。如果这冒犯了您,在 VxWorks 6.x 中您还可以使用 semOpen() API,它提供信号量名称。在每个任务中执行 semOpen 以创建/检索信号量及其 ID。
创建互斥锁后,它可用于执行 semTake 的第一个任务(无论是任务 1 还是任务 2)。
如果您需要以特定顺序发生事情,那么您需要互斥锁(用于互斥)和同步(例如通过二进制信号量)的组合。
以上面的示例为例,稍微修改一下以确保 task2 仅在 task1 完成某些操作后才运行。
/**Initialization Code**/
SEM_ID semM;
SEM_ID semSync;
semM = semMCreate (...);
semSync = semBCreate (...);
...
void task1() {
...
/* Access Shared Structure */
semTake (semM, WAIT_FOREVER);
...<Task 1 critical section>
semGive (semM);
/* Notify Task 2 that something is available */
semGive (semSync);
...
}
void task2() {
...
/* Wait for Task 1 to let me know there is something to do */
semTake (semSync, WAIT_FOREVER);
/* Access Shared Structure */
semTake (semM, WAIT_FOREVER);
...< Task 2 critical section>
semGive (semM);
...
}