Operating System Lecture No.7
Menu
API (APplication Interface)
OS を system call で呼び出して、様々な I/O 処理を行う
API の学び方
小さな例題を作って動かす。Web の情報に頼ららない。古いことが多い。特に日本語はダメ。
(英語の)マニュアルを探す。ソースコードを見る。
種類 | system call | command | rust API |
時間の制御 | select | ||
gettimeofday ? | |||
time | date | ||
utime | |||
sleep | |||
usleep | |||
変化の検出(ファイル/通信/プロセス) | select | ||
kevent | |||
inotify | |||
epoll | |||
signal | |||
getitimer | |||
ファイル管理 | |||
stat | |||
fstat ls -l | lsof | ||
プロセス管理 | |||
fork | ps,top | ||
pthread_* | |||
posix_spawn | |||
プロセス間通信 | |||
socket | netstat | ||
socketpair | |||
signal | |||
ネットワーク | |||
ip | |||
ss | |||
socket | netstat | ||
getaddrinfo | |||
bind | |||
listen, accept | |||
connect | |||
資源管理 | df | ||
システムの状態 | top | ||
USBの状態 | |||
I/Oの状態 | ioctl, fcntl | ||
fsの状態 | fstat, opendir | ||
問題7.1 Busy Wait
OSに時間を渡さないと不必要に CPU を食ってしまう。しかし、応答性は Buy wait が良い。そのバランスを考えよう。Multiple stack なネットワーク
IPv4, IPv6 が混在するネットワークでの接続を学ぶ。
問題7.2 getaddrinfo サーバとクライアント
コンピュータ上の使用可能なアドレスを探す。getaddr.pl getaddr.py.pl getaddrinfo の問題
Multicast と Bloadcast
multicast と bloadcast の問題問題7.3-4 様々な API
以下の問題を2つ選択して、API を調べる簡単なプログラムを作成し動作を調べよ。ここに載ってない Unix / Mac OS X の API を調べてもよい
Rust Cargoを使うこと Go module にすること C cmake を使うこと Java gradle を使うことGitlab CI として適切な test を用意し実行すること
test の glitlab CI のURLを提出する
Subject: Lecture on Operating System Lecture Exercise 7.3 Subject: Lecture on Operating System Lecture Exercise 7.4
- select
- keyrecord
- kevent, kqueue (BSD, OS X)
- epoll, inotify (Linux)
signal による同期
ターミナルから起動したプログラムは、^-C (コントールC) で殺すことができるが、それは、terminal (正確には pseudo tty)から singal が送られるからである。どんなsignalをどのキーで送るかは、stty で設定する。stty のマニュアルとsignal のマニュアルを調べてみよう。このあたりのキーとその動作の振舞は、stty raw とすると無効になる。すると、^-C では殺せなくなってしまう。そういうときは、top/ps で探し出して殺すことができる。
singal は、あるsignalを受け取ったときに、呼び出される関数を指定するAPIになっている。「関数へのポインタ」を表すCの型を調べてみよう。
signal では指定した関数にsingalの種類以外の情報を渡すことはできない。
signal によって中断された system call の取り扱いはどうする? エラーとして良いのか?
singnal で呼び出された関数の中では、どんなことが可能か? なんでもして良いのか? (通常は、フラグをセットするぐらいしかしない)
signal とmain()で呼び出された関数の同期はどうすれば良いか? signal で割り込まれたくない場合はどうする?
問題 Signal の動作
Signal の動作を確認してみよう。
socket によるプロセス間通信
基本的には、あっちのプロセスでwriteしたものが、 こちらのプロセスで読めるそれだけ。問題は、
どうやって、相手を指定するのか?である。
(1)共通の親を持つならば、
socketpair, pipeを使うことができる。
共通の親を持たない場合は、
(2) Unix file system の名前空間を使う (3) ネットワークの IP address + Port number を使うという手法がある。前者は、もちろん、ネットワーク経由には使えない。
socket は双方向なので、便利。(pipe は違う)
標準入出力の切替えには、close と dup を使う。
socket は、Unix に取っては file の一種であり、プロセス毎に番号(file descriptor) で管理されている。
0 標準入力 STDIN 1 標準出力 STDOUT 2 標準エラー出力 STDERRclose して open すれば、その番号が振られる。既に、open されているものをdup (duplicate ) しても良い。
以下は、3年生の shell の課題の一部である。
#include <stdio.h> const int debug=1; main() { char command1[]="wc"; char command2[]="cat /etc/termcap"; int pfd[2]; int save_in; int pid; pipe(pfd); if(pid = fork()){ save_in = dup(0); dup2(pfd[0],0); close(pfd[1]); exec(command1); if(debug) fprintf(stderr,"waiting %d\n",pid); dup2(save_in,0); waitpid(pid,NULL,0); if(debug) fprintf(stderr,"done %d\n",pid); return; }else{ if(debug) fprintf(stderr,"forked pid %d\n",getpid()); dup2(pfd[1],1); close(pfd[0]); exec(command2); exit(0); } }
socket による通信の待ち合わせ
bind
socket に名前をつけるconnect
TCP connection を張るaccept
TCP connection を受け取るTCP connection を通して、socket channel そのものを渡すこともできる。=> (fork の例題)
問題 サービスモデル
server6.pl と client6.pl を動かしてみて、サーバの動きを理解しよう。
サーバ・クライアントモデル
デーモン (daemon )
サービスとトランザクション
サービス内、トランザクション内の並列性Lock をどのように実現しているかを考えよう。
NFS
RPC と UDP という connection less の通信を使って実装されている。lock は、lockd という daemon を使う。
WWW counter
WWW server は fork するので、ファイルを lock することにより同期を取ることが多い。なので、非常に重い。File を配達するだけの WWW server と、CGI を処理するserverを分離するのが効果的。Security 的にも望ましい。
select による同期
Unix では、select call が万能であり、ほとんどの同期は select を使って実現できる。しかし、ファイルと関係しないので、計算をセーブする場合には、ファイル処理を自分で行なう必要がある。
問題 keyrecord/keyplay
real-time application を作ってみよう。キーボードの入力を時間を含めて忠実に再現する。
Application の Perfomance Tuning
Performance だけで良いのか? Real-time プログラムにとって Performance とは何か?このkeyrecord の時間の誤差はどこから来るの? Real-time OS とは?
出力ファイルを人間が読めない。出力ファイルを人間が読めるようにするには?
問題 kqueue, epoll
select は、ファイルディスクリプタの配列のコピーを伴うので、実行パフォーマンスに問題があるとされていて、Linux では epoll, inotify FreeBSD/Mac OS X では kqeueueが提案されている。
Kqueue tutorial 参考のソース(Mercurial) 学籍番号が偶数の人は、kqueue を使って、tail -f に相当するプログラムを作成せよ (Linux には kqueue )はない。timeout を使う場合と、使わない場合の両方のCPU usageを計測せよ。
問題 定期的な実行
決まった時間で実行するには、setitimer というのを使う。signal が来るので、sigpause で待とう。定期的な実行では、write system call が中断されることがある。