16

FreeRTOS(FreeRTOSV7.4.0 \ FreeRTOS \ Source \ tasks.c)でいくつかのコードを見つけました:

void vTaskSuspendAll( void )
{
    /* A critical section is not required as the variable is of type
    portBASE_TYPE. */
    ++uxSchedulerSuspended;
}

タイプが「長い」タイプである「portBASE_TYPE」であるため、保護する必要がないと明示的に言われています。私の理解では、このタイプへの自己インクリメントはアトミックであると想定しています。しかし、それを分解した後、私は証拠を見つけることができませんでした、それは単純なロード->追加->ストアです。それでは問題ですか?

void vTaskSuspendAll( void )
{
        /* A critical section is not required as the variable is of type
        portBASE_TYPE. */
        ++uxSchedulerSuspended;
 4dc:   4b03            ldr     r3, [pc, #12]   ; (4ec <vTaskSuspendAll+0x10>)
 4de:   f8d3 2118       ldr.w   r2, [r3, #280]  ; 0x118
 4e2:   1c50            adds    r0, r2, #1
 4e4:   f8c3 0118       str.w   r0, [r3, #280]  ; 0x118
 4e8:   4770            bx      lr
 4ea:   bf00            nop
 4ec:   00000000        .word   0x00000000

000004f0 <xTaskGetTickCount>:
        return xAlreadyYielded;
}
4

3 に答える 3

9

あなたが文書化したように、それはアトミックではありません。しかし、それほど厳密ではない意味で「スレッド セーフ」であるlong可能性もあります。ここでの危険の程度は、nスレッドが呼び出された場合vTaskSuspendAll、 thenuxSchedulerSuspendedが 1 ~ の間でインクリメントされることnです。

しかし、変数が完全である必要のないもの (ユーザーが中断を要求した回数のトラッカーなど) であれば、これで問題ありません。「呼び出しがどのようにインターリーブされても、この操作は同じ結果を生成する」という意味の「スレッド セーフ」と、「複数のスレッドからこれを呼び出しても何も爆発しない」という意味の「スレッド セーフ」があります。

于 2013-03-20T01:55:50.303 に答える
8

いいえ、Cの値の増分はアトミックであることが保証されていません。同期を提供するか、システム固有のライブラリを使用してアトミックなインクリメント/デクリメントを実行する必要があります。

于 2013-03-20T01:24:17.817 に答える
6

操作はアトミックではありませんが、そうであるとはどこにも書かれていません。ただし、コードはスレッドセーフですが、コードが何をしているのか、それを知るにはスケジューラの設計にどのように適合するかについてよく知っている必要があります。ロードとストアの間で他のタスクが変数を変更するかどうかは問題ではありません。これは、実行中のタスクが次に実行されるときに、元のロードが実行されたときと同じ状態の変数が検出されるためです (したがって、変更部分と書き込み部分は依然として一貫性があり有効です)。 )。

以前に投稿されたメモのように、long は、それが実行されているアーキテクチャの基本型であるため、一貫性のない状態になることはありません。しかし、コードが 8 ビット マシン (または 16 ビット) で実行されていて、変数が 32 ビットだった場合にどうなるかを考えてみてください。その場合、完全な 32 ビットが一度にではなくバイトまたはワードごとに変更されるため、スレッドセーフではありません。そのシナリオでは、コンテキスト スイッチが発生したときに、1 バイトがレジスタに読み込まれ、変更されてから RAM に書き戻されます (他の 3 バイトは変更されません)。実行された次のタスクが同じ変数を読み取ると、変更された 1 バイトと変更されていない 3 バイトが読み取られ、大きな問題が発生します。

于 2013-03-20T09:33:27.740 に答える