13

Linuxカーネルは初めてです。私の質問は、についてtask_structです。task_structEachは、親プロセスへのポインターを介して親プロセスへの参照を持っていることを知っていますtask_struct

定義の sched.h を見た後task_struct、次のことに気付きました。

struct task_struct __rcu *real_parent; /* real parent process */

compiler.h を参照していることがわかりました。「__rcu」は「読み取りコピー更新」の略だと思います

誰かが構文を明確にすることができますか?

4

2 に答える 2

13

読み取り-コピー-更新は、構造をロックすることなく、データ構造のリーダーへの同時アクセスを可能にするアルゴリズムです。ここについて 読む ことが でき ます.

カーネルが構成CONFIG_SPARSE_RCU_POINTERオプションで構築されている場合、次のよう__rcuに定義されinclude/linux/compiler.hます。

# define __rcu          __attribute__((noderef, address_space(4)))

これは、プログラマーが見落としている可能性のある特定の事柄について警告できるスパース コード分析ツールの注釈です。これが RCU にどのように関連するかについては、 で説明されていDocumentation/RCU/checklist.txtます。

__rcu スパース チェック: RCU で保護されたデータ構造へのポインタに __rcu のタグを付けます。rcu_dereference() のバリアントのいずれかのサービスなしでそのポインタにアクセスすると、sparse は警告します。

rcu_dereference()コードによって安全に逆参照できるポインターを返し、RCU メカニズムでポインターを保護するというプログラマーの意図を文書化して、Sparse などのツールがプログラミングのエラーや脱落をチェックできるようにします。

于 2013-06-15T22:30:30.550 に答える
6

RCU は「読み取り、コピー、更新」の略です。これは、ライターが同時に更新または削除できるデータに複数のリーダーがアクセスできるようにするアルゴリズムです。

RCU の下では、ライターは依然として相互排除を保証する必要がありますが、リーダーはロックを取得しません。共有データ構造が読み取り整合性に違反しない方法で更新されるように注意する必要があります。何かを削除または削除する必要がある場合、データ構造からそのアイテムのリンクを解除することはリーダーと並行して行うことができますが、メモリの実際の削除は最後のリーダーが終了するまで待たなければなりません。

リーダーにロックを取得させるのではなく、リーダーの所在を別の方法で推測します。スレッドは、実際にはロックではなく一種のグローバル フェーズである「読み取り側クリティカル セクション」に参加することにより、データ構造を参照する意図を通知できます。

たとえば、いくつかのスレッドがフェーズ 0 で RCU 読み取り側のクリティカル セクションに入ったとします。アップデーターが削除を実行し、メモリの一部を解放したいと考えています。システム内のすべてのスレッドがフェーズ 0 を空けるのを単に待つ必要があります。その間、他のリーダーはすでにデータ構造を見ていますが、RCU に意図を宣言するときに、RCU 読み取り側クリティカルを入力してそうします。フェーズ 1 の下のセクション。削除されたオブジェクトへのポインタを保持できるのはフェーズ 0 のスレッドのみです。そのため、最後のスレッドがフェーズ 0 を離れると、オブジェクトを安全に削除できます。フェーズ 1 で新しく到着したスレッドは、オブジェクトがデータ構造から削除されているため、オブジェクトを認識しません。そのため、オブジェクトを見つける方法がありません。

RCU は、「これ以上このオブジェクトにアクセスできるスレッドはありません」などの情報を知るために、「所有されている」ロック オブジェクトは必要ないという考えを利用しています。

于 2013-06-15T22:24:39.227 に答える