カーネル空間スレッドまたはプロセスがユーザー空間プロセスの子になることは可能ですか?

カーネル空間スレッドまたはプロセスがユーザー空間プロセスの子になることは可能ですか?

私はLinuxカーネルについては初心者ですが、読んでいます。原繊維に関するこの記事カーネル空間スレッドと呼ばれます(またはカーネルに残っているかどうかはわかりません)。

記事は続きます:

fibril はカーネル空間でのみ実行される実行スレッドです。 ...フィブリルには独自のスタックがありますが、それ以外は親プロセスのすべてのリソースを共有します。作業構造に関連付けられた接続のリストに保存されます。

独自のスタックがありますが、残りのメモリを親プロセスと共有することはスレッドの定義のように見えます。

しかし、私が知りたいのは、カーネルのプロセスやスレッドがユーザースペースプロセスの子になることです。それとも、すべての原繊維に1つの大きな親プロセスがあるという記事の意味を理解していませんか?私はそうは思わない。なぜなら:

プロセスには複数のアクティブフィブリルがありますが、特定の時点でそのうちの1つだけが実際にプロセッサで実行できます。

通常、fibrilは呼び出し側のユーザースペースプロセスで操作を実行する必要があります。

答え1

カーネルスレッドは実行中のスレッドです。永久的なカーネルモードで。

ps -eflコマンドを発行します。名前は角かっこ内にあるため、これらのカーネルスレッドを認識できます。また、親プロセスIDに注意を払うと、ほとんどがPID 2([kthreadd])の子であり、残りはPID 1(init [3])の子であることがわかります。

したがって、基本的にあなたの質問に対する答えは次のとおりです。いいえ!

ただし、これはスレッドがシステムコールを実行するのを防ぎません。これにより、コールの実行中にスレッドが一時的にカーネルモードに切り替わります。しかし、これはそれらを作らないカーネルスレッドしばらくの間カーネルモードで実行されるスレッドです。

したがって、カーネルスレッドのユーザープロセスの親が見つからない間に、ユーザープロセススレッド(時にはカーネルモードで実行される)を親にすることができます。


編集:以下の@Stephen Kittの興味深いコメント:

初期化はしかし〜するユーザー空間への移動は、本質的に最初から実際のカーネルスレッドにすぎません(カーネル初期化)。 (VGではありません。「一般的なプロセス」)を最初に生成する必要がありますが(PID = 1を取得するには)、kthreaddの前に予約すると、kthreadが生成されます。

コード(init/main.c)だけを見てください。

static noinline void __ref rest_init(void){
...
rcu_scheduler_starting();
...
pid = kernel_thread(kernel_init, NULL, CLONE_FS);
... 
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

答え2

カーネルスレッドは、他のカーネルスレッド(またはカーネルスレッドより前のカーネル自体)によってのみ開始できます。引用するデザインを説明するAl Viroの電子メール:

init_taskCPUで最終アイドルスレッドを開始する初期プロセスを除くすべてのプロセスdo_fork()は、カーネルスレッド、ユーザーモードプロセス、アイドルスレッドの3つのカテゴリに分けられます。関連する低レベルの操作はほとんどありません。

  • カーネルスレッドは新しいカーネルスレッドを作成できます。最も原始的な方法はですkernel_thread()
  • ユーザーモードプロセスは新しいユーザーモードプロセスを作成できます。これはsys_fork()// /によってsys_vfork()行われますsys_clone()sys_clone2()
  • カーネルスレッドはユーザーモードプロセスにすることができます。プリミティブはkernel_execve()
  • カーネルスレッドは将来アイドルスレッドを生成する可能性がありますfork_idle()。明らかにするいいえセカンダリCPUが初期化され、その状態がプロセスで大幅に上書きされるまでスケジュールされます。

どのような状況でも、ユーザーモードプロセスはカーネルスレッドまたは生成されたスレッドにすることはできません。 カーネルスレッドはこれらの操作を行いませんfork(2)

(強調します。)これは古いですが、ルールはまだ適用されています。

カーネルスレッドは常にkthreaddpid 2を持つサブスレッドです(pid 1はに予約されていますinit)。これの目的はカーネルスレッドですきれいな環境を持っている、生成方法に関係なく。これも役に立つcgroupの初期化

ユーザー空間コンポーネントによって開始された操作によって、カーネルスレッドが開始される可能性があります(たとえば、カーネルモジュールのロードまたはファイルシステムのマウント)。ただし、カーネルスレッドはカーネルによって開始され、カーネルに対して操作を実行し、別のユーザースペースプロセスに関連付けられていません。kthreadd 例えば信号処理の目的で使用されます。

角かっこ内に表示されるプロセスは、必ずしもカーネルスレッドである必要はありません。コマンドラインなしのプロセス

関連情報