プロセスを学ぼうchikuwait12019/08/24 ゆるい勉強会 in はこだて#3
View Slide
chikuwaitです• Twitter : chiku_wait• 高度ICTコース B4• システムソフトウェア研究室• OSや仮想化技術(ハイパーバイザ,コンテナ)などのシステムソフトウェア(低レイヤ)が好き• Linux(を使うことではなく仕組みなどが)が好き自己紹介2
• オープンソースOSのLinuxのプロセスをメインで扱います• 対象のソースコードはLinux kernel 2.6前提3
動作中のプログラムのこと• 処理実行の基本単位で、独立した仮想メモリ空間を持つ• バグで異常終了しても他のプロセスには影響を与えない• プロセスは同一メモリ空間などを共有する1つ以上のスレッドからなる• スレッド:1つのプロセス内で複数の処理を同時に実行できる実行単位プロセスとは4Windows だとこれ→
プロセスとスレッドの関係5プロセス1共有メモリスレッド2スレッド1プロセス2共有メモリスレッド1
• プロセスを生成したときに生成した側が親、された側が子になる• プロセスは複数の子を持つことができ、その子が更に子を持てる(孫)• 最も遠い祖先はinitプロセス• 全てのプロセスはinitプロセスを起原にもつプロセスの親子関係6initlogin …shvim …
• 大きく分けてテキスト、データ、スタックに分割• データ:グローバル変数、static変数、malloc() 等で確保したもの• スタック:関数の局所変数と、関数の引数• スタックの底:引数と環境変数• 0番地付近は、メモリを割り当てない• いわゆるNULLポインタプロセスのメモリ構造7カーネル領域スタック(局所変数等)ヒープ(mallocで確保)初期化なし静的変数初期化付き静的変数テキスト(機械語)Low addressHigh address
task_struct構造体(include/linux/sched.h)• state:プロセスの実行状態を表現• thread_info:カーネルに関する低レベル情報とカーネルスタックの保持• mm:プロセスのメモリ管理• binfmt:実行ファイルローダ• pid:プロセスIDLinuxカーネルにおけるプロセスの表現8volatile long state(TASK_XXX)struct thread_info* thread_infounsigned long flags…prio_array_t* array…struct mm_struct *mmStruct linux_binfmt* binfmt…pid_t pid…
TASK_RUNNING• あるCPUで実行中華、実行可能でCPU割当を待っているTASK_INTERRUPTIBLE• シグナルが受信可能で待機している(シグナルを受信すると起床する)TASK_UNINTERRUPTIBLE• シグナル受信不可で待機中TASK_STOPPED• 実行停止中(SIGSTOPなどを受信したり、ptraceで実行停止中)8つのプロセス実行状態(1/2)9
TASK_TRACED• Ptraceによるトレース対象になっているTASK_NONINTERACTIVE• 非対話的処理(スケジューラへのヒント)EXIT_ZOMBIE• 通称ゾンビ状態、実行終了して親プロセスによるwait待ちEXIT_DEAD• 実行終了して、task_structを開放中8つのプロセス実行状態(2/2)10
プロセスの状態遷移11TASK_RUNNING(実行中)TASK_STOPPEDTASK_RUNNING(実行待ち)TASK_UNINTERRUPTIBLETASK_INTERRUPTIBLEEXIT_ZOMBIE EXIT_DEADプロセス開放プロセス生成fork,cloneexecclone(CLONE_STOPEED)ptrace_notify()起床プリエンプトスケジューリング起床起床do_exit()waitexitwait
プロセスのライフサイクル12cloneexecvedo_forkcopy_processロード実行do_fork():fork/vfork/cloneシステムコールの実体• 共有する資源のフラグ、スタックサイズなどが引数• 処理の大半は資源の複製を作成• e.g. CLONE_VM:メモリ空間(mm_struct)の共有copy_process():資源の複製処理の実体• do_forkのフラグの指定によって参照を増やしたりメモリを確保したりする• task_struct構造体などの複製do_execveバイナリローダ終了 exitdo_exit
プロセスのライフサイクル13execve():execファミリのシステムコール• 今まで使用していた空間を破棄して新たな空間にプログラムをロードするdo_execve()• ファイル名、環境変数、引数のページをコピー• コピーした領域はexec後にマップする• バイナリローダを試すcloneexecvedo_forkcopy_processロード実行do_execveバイナリローダ終了 exitdo_exit
プロセスのライフサイクル14バイナリローダ:実行ファイルをメモリ上に展開• Linuxは複数の実行ファイルフォーマットが使用できるので、それに合わせて切り替える• e.g. ELFローダ:fs/binfmt_elf.cdo_exit():プロセス終了時に呼び出される• exit_notify():プロセスが終了したことを親に通知• reparent():終了したプロセスの子プロセスを他のプロセスの子プロセスにする• __exit_mm():mm_structの開放cloneexecvedo_forkcopy_processロード実行do_execveバイナリローダ終了 exitdo_exit
なるほどわからん15
3年のオペレーティングシステムの授業でやるはず(Linuxのソースコードまでは触れない)16
OSの気持ちがほんの少しだけ分かるようになる• 別にプロセスを知ったところで、今日からOSを作れる訳でもないし、アプリを作れるようになるわけでもないです• 別に普段考えなくていいけど、知らないで考えないより、知った上で任せる方が良いですよね• OSの挙動や仕組みを知ることで、普段書いているプログラミングで使っている仕組みを理解することができる e.g. Threadで、プロセスが分かって何になるの?17