システムプログラム 練習問題 #3

練習問題(301)

以下のプログラムのそれぞれで,コピー元のファイルをサイズが大きなファイルに変更し,バッファサイズを様々に変えて実行時間がどう変化するかを調べよ.

  1. (1) ライブラリ関数である fgetc, fputc を用いてファイルコピーを行うプログラム(このプログラムを参考にすると良い)
  2. (2) ライブラリ関数である fgets, fputs を用いるように(1)を変更したもの
  3. (3) ライブラリ関数である fread, fwrite を用いるように(1)を変更したもの
  4. (4) システムコールである read, write を用いてファイルコピーを行うプログラム(このプログラムを参考にすると良い)
バッファサイズとしては,最低64バイト程度の小さいものから最大128 MB 程度の大きなものまで,対数軸に載るような間隔で少なくとも8つ以上を使用すること. 実行時間を計測する際には,同じパラメータで何度か実行して複数の実行時間の平均値をとること. (1) では,バッファサイズは変化させなくて良い. ファイルはある程度の文字数ごとに改行を含むものにすること((2) と (3) は何が違うのかを意識しよう).

この練習問題では実行時間の測定を macOS 上で行っても Linux 上で行っても良い.

結果はどうなっただろうか? 実行時間の違いについて考察せよ.

プログラムの実行時間は time コマンドを用いて計測することができる. しかし,このプログラムではファイルコピー以外の部分(例えば malloc や free)の実行にかかる時間が非常に長い可能性があるため,プログラムの中で clock, clock_gettime, gettimeofday 関数などを呼び出すようにし,2つのファイルのオープンからクローズまでの部分だけの時間を計測することを勧める.

演習で使う計算機環境では,各人が使えるディスクサイズに上限があることに注意しよう.quota コマンドでその上限と現時点での自分の使用ディスクサイズを見ることができる. 実験の後には,もう使用しない大きなファイルは消去しておくこと.消去しないと,誰よりもまず自分が困る.

練習問題(302)

システムコールを用いてファイルをコピーするプログラムを1文字単位ではなく BUFSIZ 単位で読み書きするように変更しなさい. サイズが BUFSIZ であるデータの読み書きを要求しても,実際に読み書きされるデータのサイズが BUFSIZ 以下になる場合もあることに注意せよ.

練習問題(303)

コマンドライン引数で指定されたファイルの末尾を,コマンドライン引数で指定された行数だけ表示する tail コマンドに似たプログラムを mmap 関数(mmap システムコール)を用いて作りなさい.

練習問題(304)

utmp ファイルの各エントリの内容を保持するリストを作るプログラムは,utmp ファイルを用いない Mac OS X ではうまく動作しない. そこで,getutxent(3) を用いて10秒おきに utmpx ファイルを読み込み,内容に変更があった場合のみ,変更部分を現在時刻とともに出力するような,Mac OS X で動作するプログラムを作りなさい. このプログラムの出力の一例を以下に示す. 出力のフォーマットは各自の好みに合わせて変えて良い.

$ ./a.out

Sat Mar 17 11:12:36 2017
Added:
        |                |        |Tue Mar 14 13:50:12 2017
   oyama|crocus05.coins.t| ttys000|Sat Mar 17 10:52:31 2017

Sat Mar 17 11:12:56 2017
Added:
   oyama|crocus06.coins.t| ttys001|Sat Mar 17 11:12:53 2017

Sat Mar 17 11:13:16 2017
Added:
   oyama|crocus07.coins.t| ttys002|Sat Mar 17 11:13:15 2017

Sat Mar 17 11:14:31 2017
Removed:
   oyama|crocus06.coins.t| ttys001|Sat Mar 17 11:12:53 2017

Sat Mar 17 11:15:16 2017
Added:
   oyama|crocus08.coins.t| ttys001|Sat Mar 17 11:15:15 2017
Removed:
   oyama|crocus07.coins.t| ttys002|Sat Mar 17 11:13:15 2017

内容に変更があったかどうかは,ファイルの更新時間ではなく前回読み込んだ内容との比較によって判断するものとする. struct utmpx を含むリスト(linked list)を用いて記憶し,それらを比較対象とするものとする. 表示するエントリは,struct utmpx のメンバ ut_type が DEAD_PROCESS ではないもののみとする.

実行結果は,端末を開いたり閉じたりといった utmpx ファイルの内容を変更する操作を繰り返し,正しく動作していることがわかるものにしなさい.

練習問題(305)

getutxent のマニュアルに記載されている通り,struct utmpx の中の有効であるメンバは ut_type の値によって異なる. その結果,無効なメンバのための使われないメモリ領域を含む struct utmpx 型の構造体が存在しうる. また,struct utmpx の中の配列は余裕を持った大きさに設定されており,struct utmpx 型の構造体はメモリに関して無駄が多いと言える. メモリ資源の消費量を非常に小さく抑えたい状況を想定し,練習問題(304)のプログラムを変更して,getutxent が読み込んだエントリのうち必要な部分だけを格納するための必要最小限のメモリを確保するようにしなさい.