オペレーティングシステムのお勉強2
この記事はオペレーティングシステムのカーネルの動作原理などを勉強するためにまとめたものです。
(テスト勉強も兼ねてますので暖かくみていってください。)
Linuxについて
Linuxのディレクトリ構成
まず前提として、本記事では/home/rikut0904/をホームディレクトリとして説明をしていきます。
それぞれのディレクトリの利用用途等についてまとめると以下の表のようになります。
| ディレクトリ名 | 概要 |
|---|---|
| home | ユーザーのホームディレクトリを保存するためのディレクトリ |
| root | 管理者用のホームディレクトリ |
| etc | システムの設定ファイルを格納しておくためのディレクトリ |
| tmp | 一時利用を目的とした作業用ディレクトリ。多くの環境では再起動で内容が削除される |
| usr | 共有可能なプログラムや、コマンドを保存しておくためのディレクトリ |
| lib | カーネルモジュールや基本ライブラリなどを保存しておくためのディレクトリ |
| bin | ファイル操作などの基本的なプログラムが保存されているディレクトリ |
| sbin | 管理者向けのコマンドを保存しておくためのディレクトリ |
| var | ログやキャッシュなどを保存しておくためのディレクトリ |
| sys | 稼働中のドライバ関係の情報を保存しておくための仮想的なディレクトリ |
| dev | デバイスファイルを格納しておくためのディレクトリ |
| proc | システムやプロセス情報を保存しておくための仮想的なディレクトリ |
Linuxの基本コマンド
ファイルリストを表示
$ ls #カレントディレクトリ内のファイルリストを表示
$ ls -l #カレントディレクトリ内のファイルリストの詳細を表示
$ ls -a #カレントディレクトリ内の隠しファイルを含めた全ファイルリストを表示
$ ls ./a #/aディレクトリ内のファイルリストを表示
ファイルの内容を表示
$ cat ./a.txt #カレントディレクトリ内のa.txtファイルの内容を表示
$ cat -n ./a.txt #カレントディレクトリ内のa.txtファイルの内容を行番号付きで表示
$ less ./a.txt #カレントディレクトリ内のa.txtファイルの内容を一行ずつ表示
ディレクトリ関連
カレントディレクトリの確認
$ pwd
ディレクトリ移動
$ cd .. #一つ上の階層へ移動
$ cd a #カレントディレクトリ内のaディレクトリへ移動
ディレクトリの作成・削除
$ mkdir b #カレントディレクトリ内にbディレクトリを作成
$ rm a.txt #カレントディレクトリ内にあるa.txtファイルを削除
$ rm -rf b #カレントディレクトリ内にあるbディレクトリを削除
プロセス関連
$ ps -a #端末から起動しているプロセスをリストアップする
$ kill プロセスID #プロセスIDを終了する
プロセスの標準入出力
プロセスには標準でファイルを読み書きするための3つの入出力チャンネルを持っている。
- 標準入力
- 標準出力
- 標準エラー出力
これらを用いてC言語ではscanf()やprintf()、perror()などが作成され、利用している。
ターミナルから起動したプログラムは通常、ターミナルやプログラムから記述した文字列を標準入力に入れ、処理をしたのち標準出力や標準エラー出力から返答が来る。これらはすべてターミナルへとつながっているため、入力処理やターミナルに書き出すということがおこなえる。
また、リダイレクトやパイプを用いることで、標準入出力とは別の箇所へ接続して処理を続けることができるようになる。
リダイレクト(<,>)
プロセスの標準入出力を切り替えることができる機能。コマンドの出力をファイルに送ったり、ファイルの入力をコマンドに送ったりすることができる。
$ ls
a.out
app.c
$ ./a.out
a = 5
b = 6
a + b = 11
$ ./a.out > out.txt
$ cat ./out.txt
a = 5
b = 6
a + b = 11
$ ./a.out < in.txt > out2.txt
$ cat out2.txt
a = 5
b = 6
a + b = 11
パイプ(|)
プロセスの標準出力を別のプロセスの標準入力につなぐための機能。
$ find /usr/include | grep "std"
...
システムコール
ユーザープログラム向けに提供されているコマンドのこと。
例:cd、mkdirなど
システムコールを利用する際には、Cライブラリ内のラッパー関数を介して呼び出すか、syscall()関数でシステムコール番号を指定して呼び出す方式がある。
プロセスのシステムコールのトレース
そのプロセスがどのようなシステムコールを実行したのかを確認することができるコマンドをstraceコマンドという。
$ starce -f -c コマンド名
そのプロセスで一回以上呼び出されたシステムコールの情報が表示される。
ファイルの入出力用システムコールと標準Cの入出力関数の対比
| システムコール | 低水準I/O関数 | 高水準I/O関数 |
|---|---|---|
| openat | open() | fopen() |
| read | read() | scanf(), fread(), fscanf(), fgets() |
| write | write() | printf, fwrite(), fprintf(), fputs() |
| close | close() | fclose |
| lseek | lseek() | fseek() |
プロセスが低水準I/O関数を呼び出すことで、関連するシステムコールが呼び出されてファイルアクセスがおこなわれる。この時操作対象のファイルはファイルディスクリプタという番号で指定する。高水準I/O関数を呼び出すと、ストリームの読み書きがおこなわれる。
ファイルディスクリプタ
プロセスがファイルを開くたびにカーネルから割り当てられる番号であり、0番は標準入力、1番は標準出力、2番は標準エラー出力が割り当てられている。低水準入出力関数open()が実行されるとOSによって新たにファイルディスクリプタが割り当てられる。
ストリーム
システムコールの回数を削減し、一度のシステムコールで実行するデータ転送量を増やすという仕組みのことであり、システムコールを呼び出す回数が減る分効率的に読み書きすることができる。
dup2
ファイルディスクリプタを複製するためのシステムコール。dup2(oldfd, newfd);で指定して利用する。
pipe
パイプを作成するためのシステムコール。pipe( pipefd[2] );で指定して利用する。