シェルがプロセスを実行するしくみ

シェルはプロセスを直接実行しない Link to this heading

カーネル以外のプロセスは、新しくプロセスを実行できない。そのため、シェルでプロセスを実行するためには、シェルからカーネルにプロセスの実行を依頼しなければならない。

カーネルへの依頼にはシステムコールを使う Link to this heading

カーネルになにかの処理を依頼するためには、システムコールを使う。システムコールは、ユーザプログラムがカーネルに処理を依頼するためのインターフェースである。

シェルからカーネルへのプロセスの実行依頼 Link to this heading

シェルからカーネルへのプロセスの実行依頼は、forkシステムコールとexecveシステムコールを使って行う。なお、プログラミング言語からは、これらのシステムコールに対応するライブラリの関数を呼び出すことになる。

forkシステムコールを呼び出すと、カーネルは呼び出し元のプロセスのコピーを作成し、新しいプロセスを生成する。この時点で生成されるプロセスは呼び出し元のコピーであるため、呼び出し元のプロセスと同じプログラムを実行する。

pid = os.fork()

forkで生成したプロセスに新しいプログラムを実行させるには、execveシステムコールを呼び出すexecveシステムコールでは、プログラムのパス名と引数を指定する。これを呼び出すと、プロセスのプログラムが指定したプログラムに置き換わる。

if pid == 0:  # Child process
    os.execve('/bin/ls', ['/bin/ls', '-l'], os.environ)

プロセスの入出力のリダイレクト Link to this heading

forkで複製された処理の標準入力・標準出力・標準エラー出力は、ファイルディスクリプタとして親プロセスから子プロセスへコピーされる。これにより、親プロセスと子プロセスは独立して処理できる。

子プロセスのファイルディスクリプタをリダイレクト先に変更することで、標準入力・標準出力・標準エラー出力をリダイレクトできる。

ファイルディスクリプタの変更は、dup2システムコールを使って行う。dup2システムコールは、指定したファイルディスクリプタを、指定したファイルディスクリプタ(の番号)へコピーする。

# 標準入力をリダイレクト
# stdin_fd: リダイレクト先のファイルディスクリプタ
# sys.stdin.fileno(): 標準入力のファイルディスクリプタ
os.dup2(stdin_fd, sys.stdin.fileno())

プロセスのパイプ Link to this heading

あるプロセスの出力を別のプロセスの入力につなぐことをパイプという。

パイプは、pipeシステムコールを使って作成する。pipeシステムコールを使うと、読み込み用と書き込み用の2つのファイルディスクリプタが生成される。

pipe_read, pipe_write = os.pipe()

これらのファイルディスクリプタをパイプ前の出力とパイプ後の入力にリダイレクトすることで、パイプを実現できる。

参考文献・URL Link to this heading

Licensed under CC BY-NC-SA 4.0
最終更新 6月 16, 2024
Hugo で構築されています。
テーマ StackJimmy によって設計されています。