Operating System Lecture No.7

Menu


API (APplication Interface)

OS を system call で呼び出して、様々な I/O 処理を行う


API の学び方

小さな例題を作って動かす。

Web の情報に頼ららない。古いことが多い。特に日本語はダメ。

(英語の)マニュアルを探す。ソースコードを見る。

API の種類
種類 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
少なくとも一つの言語のAPIに関して、全部を見たことがある必要がある。

go lang standard library


問題7.1 Busy Wait

OSに時間を渡さないと不必要に CPU を食ってしまう。しかし、応答性は Buy wait が良い。そのバランスを考えよう。

Busy 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

  1. select
  2. keyrecord
  3. kevent, kqueue (BSD, OS X)
  4. 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   標準エラー出力   STDERR

close して 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 が中断されることがある。


Shinji KONO / Fri Dec 20 14:30:41 2024