この問題について誰か助けてください。VxWorks で同じ重要なリソースを保護するために、2 つの異なるタスクが 2 つの異なるセマフォを作成することは可能ですか?
2 に答える
ここで何かが欠けていると思います。
vxWorks では、すべてのタスクが同じメモリ空間を共有するため、タスク間のグローバル データを Mutex で保護する必要があります。
アイデアは、1 つの Mutex のみを使用することです (その sem_id は、それを使用するすべてのタスクでよく知られています)。
1 つの 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 にはいくつかのオプションがあります。
システムの init でミューテックスを作成できます (推奨)。
ミューテックスが読み取られず、sem_id がまだゼロの場合、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) で使用できます。
特定の順序で物事を行う必要がある場合は、ミューテックス (相互排除用) と同期 (たとえば、バイナリ セマフォ経由) の組み合わせが必要です。
上記の例を少し変更して、task1 が何かを行った後にのみ task2 が実行されるようにします。
/**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);
...
}