ファイル入出力と プロセス間通信 (2) 2004年12月16日 海谷 治彦.

Slides:



Advertisements
Similar presentations
1 ファイル入出力と プロセス間通信 (1) 2004 年 12 月 10 日 海谷 治彦. 2 目次 まずはマニュアルをみよう. –2 章 システムコールインタフェース –3 章 汎用関数定義 アンバッファー化入出力 (Unbuffered I/O) –open, read, write... –lseek,
Advertisements

システムプログラミング 第11回 シグナル 情報工学科 篠埜 功. 今回の内容 前回の補足( exit システムコールについ て) プロセス間通信 – シグナルの送信 --- 今回の内容 – パイプによる通信 – ソケットによる通信.
ネットワーク・プログラミ ング カーネルの役割とプロセス生成. 1.1 OS の役割 仮想マシン OS はハードウェアの多様性 をカプセル化し、利用者を 複雑な処理から開放する。 プロセス管理 時間多重化により各プロセ スに CPU を割当てる。 メモリ管理 メモリ空間の多重化により、 各プロセスにメモリを割当.
プロセスの生成とコマンドの実行 プロセスの生成とコマンドの実行 プロセス生成のシステムコール プロセス生成のシステムコール プロセス生成のプログラム例 プロセス生成のプログラム例 プログラム実行のシステムコール プログラム実行のシステムコール 子プロセスの終了を待つシステムコール 子プロセスの終了を待つシステムコール.
システムプログラミング 第10回 情報工学科 篠埜 功. 今回の内容 プロセス(続き) – execve システムコール 現在のプロセスを、引数に与えられたファイル(実行 形式ファイルあるいはシェルスクリプト等の実行可能 なファイル)を受け取り、現在のプログラムをそれで 置き換える(変身)。 fork.
目次 このドキュメントについて・・・前提条件……………………………………… 2
セキュリティ機構のオフロードを考慮した仮想マシンへの動的メモリ割当
JXTA Shell (3) P2P特論 (ソフトウェア特論) 第6回 /
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
UNIXマシン間のファイル転送 2002年10月20日 海谷 治彦.
システムプログラミング 第6回、7回 main関数の引数 usageメッセージ システムコールのエラーメッセージ ファイル
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
Advanced Unix Commands
リダイレクト パイプ 標準入出力プログラム コマンド行引数 関数 system()
山田 由貴子 (北大理・地球惑星科学専攻) 2004年10月29日
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
オペレーティングシステム (OSの機能と構造)
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング システムプログラミング プロセス間通信(パイプ) 担当:青木義満
アルゴリズムとデータ構造 補足資料6-3 「サンプルプログラムcat3.c」
オペレーティングシステム i386アーキテクチャ(2)
Telnet, rlogin などの仮想端末 ftp などのファイル転送 rpc, nfs
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
ネストした仮想化を用いた VMの安全な帯域外リモート管理
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング 第11回 プロセス間通信4 仮想FTPの実現 担当:青木義満
UNIXについて 松野秀平.
Linux リテラシ2006 第6回 デーモン CIS RAT.
オペレーティングシステム2004 プロセス (1) 2004年10月8日 海谷 治彦.
10: ファイル入出力 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング演習3 第2回 GUIの復習.
プログラミング 2 ファイル処理.
システムプログラミング 第9回 、10回 ハードリンク、シンボリックリンク プロセスの生成
システムプログラミング 第12回 プロセス間通信 情報工学科 篠埜 功.
オペレーティングシステム2006 第1回 概要 2006年10月12日 海谷 治彦.
マルチスレッド処理 マルチプロセス処理について
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
リダイレクト パイプ 標準入出力プログラム コマンド行引数 関数 system()
オペレーティングシステム イントロダクション
演習1の解答例の解説 2004年10月21日 海谷 治彦.
Java/Swingについて+ (4) 2005年10月26日 海谷 治彦.
演習1の解答例の解説 2006年11月8日 海谷 治彦.
JXTA Shell (1) P2P特論 (ソフトウェア特論) 第4回 /
TCP/IPとプロセス間通信 2007年1月12日 海谷 治彦.
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング 第6回 システムプログラミング概要 プロセスの生成 担当:青木義満
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
第4回 ファイル入出力方法.
JXTA Shell (2) P2P特論 (ソフトウェア特論) 第5回 /
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
OSが管理している、デフォルトの入出力装置 入力:stdin キーボード 出力:stdout モニタ(コマンドプロンプトの画面)
オペレーティングシステム (OSの機能と構造)
プログラミング演習I 2003年7月2日(第11回) 木村巌.
システムプログラミング 第12回 プロセス間通信 情報工学科 篠埜 功.
サーバ・クライアントシステム (X Window System )
システムプログラミング 第6回 システムコールのエラーメッセージ ファイルシステム 情報工学科 篠埜 功.
オペレーティングシステムJ/K 2004年10月4日
システムプログラミング 第12回 プロセス間通信 情報工学科 篠埜 功.
ネットワーク・プログラミング デバイスドライバと環境変数.
システムプログラミング 第10回 プロセス間通信3 簡易Web server(準備) Chat プログラム 担当:青木義満、篠埜 功
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング 第11回 プロセス間通信4 仮想FTPの実現 担当:青木義満
強制パススルー機構を用いた VMの安全な帯域外リモート管理
システムプログラミング 第9回 、10回 ハードリンク、シンボリックリンク プロセスの生成
アルゴリズムとデータ構造 補足資料6-1 「サンプルプログラムcat1.c」
オペレーティングシステム (OSの機能と構造)
Cp-1. Microsoft Visual Studio 2019 C++ の使い方 (C プログラミング演習,Visual Studio 2019 対応) 金子邦彦.
ネットワーク・プログラミング パイプライン通信とシグナル.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
情報処理Ⅱ 2005年11月25日(金).
ネットワーク・プログラミング プロセスとファイルシステム管理.
強制パススルー機構を用いた VMの安全な帯域外リモート管理
Presentation transcript:

ファイル入出力と プロセス間通信 (2) 2004年12月16日 海谷 治彦

目次 ターミナルとコンソール (tty) リダイレクションの実装 パイプ パイプによるプロセス間通信 簡易なプロセス間通信 デバイスドライバへの伏線 リダイレクションの実装 パイプ パイプによるプロセス間通信 簡易なプロセス間通信

ターミナル,コンソール 入門的なCプログラム等で必ず利用されるユーザーインタフェース. ちょっと使うのが退屈.

初期(~1990年)のUNIX環境(1) UNIXマシンは個人で占有せず, 端末装置(ターミナル)を使って,共有利用した. サーバー ソレ自体は頭の良くないコンピュータ,通信機能くらいしかない. サーバー (UNIXマシン) 端末 端末 端末

初期(~1990年)のUNIX環境(2) UNIXマシンと端末は,かなり遅い通信回線で結ばれていた. RS232C等を用いたシリアル回線. 9600bps程度. 今のイーサが100Mbps (100,000,000bps) テキストを入力して,テキストで結果が返ってくる単純な入出力処理のみを行った. グラフィク等は扱えない. サーバー (UNIXマシン) 端末 端末 端末

初期(~1990年)のUNIX環境(3) コンソールはマシンに直結されているモニタと入力装置を指す. セキュリティ上の理由等から特権的な処理(システムの停止等)はコンソールからでないとできないようになっている場合が多かった. サーバー (UNIXマシン) コンソール 端末 端末 端末

今のUNIX系OS環境(1) マシンを個人が占有するようになった. > コンソールを直接使うようになった. > マルチユーザー,マルチプロセスの意識が希薄になった. コンソールを直接使うようになった. 初期にはコンソールは管理目的以外には使わないことが多かった. コンソールはマルチウインドウシステムを採用するようになった. > >

今のUNIX系OS環境(2) コンソール中に仮想端末 (擬似端末 pseudo terminal, 普通ptyと呼ぶ) を作るようになった. アプリケーションの1つとして動作している. 昔の端末を模倣している. 無論,端末的なWindowだけでなく,表計算ソフト等,多様なアプリも動く. > >

今のUNIX系OS環境(3) ネットワーク経由で他のマシンのptyを呼び出すことが可能となっている. 昔の端末みたい. 一般に他のマシンのサービスを利用する方法は現在では多数存在する. > > ネットワーク >

他のマシンのサービスを利用 仮想端末を利用 Windowシステムごと呼ぶ. 関数呼び出しレベルで他のマシンに処理を依頼. telnet や rsh, ssh を利用する方法がコレ. 旧来の端末利用を模倣している点で旧人類にも受け入れやすい. Windowシステムごと呼ぶ. 他のマシンのWindowシステムの一部を呼び出す方法.VNCやMSも似たようなソフトを提供していたはず. UNIX標準のX window システムはGUIをリモートで呼び出す機能を開発当初から備えていた. Windowsはこの辺が弱い. 関数呼び出しレベルで他のマシンに処理を依頼. RPCやRMIと呼ばれるリモート手続き呼び出しの類. HTTP等に基づくウエブサービスも分類的にはコレ. FTPクライアントもコレかな?微妙.

他マシン呼び出しの複雑な呼び出し例

前ページの構成 ユーザーはWindows PCを利用 以上,前ページの画面には4つの異なるマシンのインタフェースが見えている. 擬似端末呼び出しソフト(Teraterm)でlinux2001の擬似端末を呼び出す. VNCでlinux2002上のWindowシステムを呼び出す. 目玉のアプリ (xeyes) 時計 (xclock) 文書表示 (ghostscript) kterm (擬似端末) ココからさらにsshしてホストwwwの擬似端末を呼び出す. 以上,前ページの画面には4つの異なるマシンのインタフェースが見えている.

(擬似)端末装置のOS的な説明 端末(モニタとキーボード)の制御はOSが行っている. 端末で起動されるアプリからは, 詳細は次回だが,この制御を行うOSの部分をttyドライバ (デバイスドライバの一種)と呼ぶ. ttyはTele Type writer が由来らしい. 端末で起動されるアプリからは, キーボード ⇒ ファイルディスクリプタ0番 stdin モニタ ⇒ ファイルディスクリプタ1と2番 stdout と stderr として見えている.

端末の3つの特殊機能 通常のファイルI/Oとは異なり,端末の入出力では以下の3つを考慮しなければばらない. エコーバック機能 バッファ機能 キーボードから入力された文字が画面に表示される. バッファ機能 エンターを押すまで文字をアプリに送付しない. ファイルストリームのバッファとはまた違う(涙) シグナル機能 特定のキー入力により,アプリにシグナルを送ることができる. 例: コントロールCで強制終了,コントロールZで中断等. 上記機能はシステムコール(ioctl)によって無効にすることもできる(が,かなり高度で危険なプログラミング).

エコーバックとバッファの例 キーボード モニタ SAKANA マシン OS アプリ ttyドライバ S A K N 打ち込んだだけではアプリに伝わってないが,画面には表示される. SAKANA SAKANA マシン OS アプリ ttyドライバ S A K N

バッファの例 キーボード モニタ エンターを押すと,やっとアプリに伝わる. SAKANA エンター マシン OS アプリ ttyドライバ S

結果を標準出力に返すなら キーボード モニタ やはりttyドライバを経由して画面に返す. SAKANA エンター マシン OS アプリ TAKO

シグナルの例 キーボード モニタ キーボードでプロセスの制御(一部)を行える. コントロールC ttyドライバ 殺す OS アプリ マシン プロセスの殺害依頼

データがディスク等に届くまで 再録 ユーザープロセス カーネル write()等 fprintf()等 バッファ キャッシュ ディスク 等

データが端末に届くまで ユーザープロセス カーネル write()等 ttyドライバ fprintf()等 バッファ バッファ 端末装置

端末のIDと制御 端末装置はファイルの一種として識別できる. ttyというコマンドで該当する端末のIDとなるファイルを知ることができる. sttyというコマンドで前述の3つの機能をある程度,制御できる. 制御だけでなく現状の設定もしることができる.

ttyとsttyの利用例

端末入出力のまとめ 歴史的経緯もあり結構複雑. 初級のプログラム開発練習は端末上で行われるが,初心者には理解不能な挙動をたまにするのは,ここで話したような複雑な構造があるため. しかし,プロのコンピュータ技術者ならこの程度の理解は必須.

shell, コマンドインタプリタ 通常,端末の上ではテキストによるコマンドを実行するための対話型プログラムが動作している. 代表例 bash (/bin/bash) Linuxでは標準らしい. tcsh (/bin/tcsh) 別のshell

リダイレクション shellからコマンドを呼ぶ場合,< や > の記号を使って, 本来ならキーボードから入力するデータをファイルから入力する (<) 本来ならモニタに出力されるデータをファイルに出力する (>) ということができる. これらの機能?をリダイレクション(redirection)と呼ぶ. リダイレクションを <や>の記号で実行できるのは,あくまでshellの機能であり,OSの機能ではない.

リダイレクションの実現 以下のシステムコールを使って実現されている. openで読み先(書く先)を開ける. closeで標準入力(出力)を閉める. ttyドライバとの接続が切れる. dupで1で開けたディスクリプタの複製を標準入力(出力)が接続されていたディスクリプタに繋ぐ. 1で開けた本来のファイルディスクリプタを閉じる. これは開けたままにしておく場合もある.

例: 読み先の変更 // 前略: ex4brd.c 演習4の解答例の改造版 main(int argc, char* argv[]){ // 中略 int fd; if((fd=open("fd2.e2fs", O_RDONLY))<0) exit(5); close(0); dup(fd); close(fd); // load all blocks in the file system. if(read(0, blocks, ALLBLOCKSIZE)!=ALLBLOCKSIZE) exit(3); // 以下略 }

解説 openでファイルをあける. closeで標準入力(キーボード)を切断. dupで複製. もとのディスクリプタをcloseで閉じる. b. close プロセス 1 2 3 c. dup fd2.e2fs ディスクリプタ表 a. open d. close

shellは何をしているか? shellが < > の記号とファイル名を受け取った場合, 前述のopen, close, dup, 等を使ったプログラムと同じことを処理してくれている. 結果として,UNIX流のプログラムは,標準入力からデータを得て,出力へデータを示すように(簡易に)プログラムしても実際上,不便がないし汎用性がある. 「ファイル名をいれてください」などとアプリ側で対処するプログラムは汎用的でない.

パイプ shellにおいて,複数のコマンドを | (縦棒?)で繋ぐことで, このような機能をパイプとかパイプラインとか呼ぶ. | の前にあるコマンドが標準出力に送るはずのデータを, | の後にあるコマンドに受け取らせることができる. このような機能をパイプとかパイプラインとか呼ぶ. パイプを | の記号で実行できるのは,あくまでshellの機能であり,OSの機能ではない.

pipeシステムコール 読み用と書き用のファイルディスクリプタを生成し, 書き側にデータを書くと,読み側からそのデータを読めるような接続を確立する. 単一プロセスでpipeを生成してもほとんど意味が無い(涙) 何故意味ないかは左図参照. プロセス 3 4 5 6 1 ココが パイプ ディスクリプタ表

OSから見たpipe pipeを通るデータはカーネル内でバッファリングされている. pipe自体はiノード番号がつけられる. 読み書きそれぞにファイルオブジェクトが割り当てられる. カーネル プロセス 3 4 5 6 1 ファイル オブジェクト バッファ ディスクリプタ表 ファイル オブジェクト

例 (はげしく無意味なプログラム) 画面へ 1 3 buf 4 プロセス 5 6 str 引数 から // pipe1.c main(int argc, char* argv[]){ int pipes[2]; char* str; char buf[100]; int r, w; if(argc<2) exit(2); str=argv[1]; if(pipe(pipes)<0) exit(1); w=write(pipes[1], str, strlen(str)); r=read(pipes[0], buf, w); write(1, buf, r); printf(", data %d bytes, write %d bytes, read %d bytes.\n", strlen(str), w, r); } プロセス 画面へ 3 4 5 6 1 buf ディスクリプタ表 str 引数 から

forkとの連携 shell上のパイプ(|)を実現するためには,通常,以下のような処理がされる. pipeを作る. 子プロセスの読みパイプを閉じる. 親プロセスの書きパイプを閉じる. 子から親にパイプを通してデータ通信ができる. ファイルの読み書きと同様の手順で. 本来の標準入力,出力を閉じて,Dupする. オプション 親子それぞのプロセスはpipeで作ったディスクリプタではなく,標準の入出力ディスクリプタを使うことができる.

ステップ1 パイプを作る カーネル プロセス 3 4 5 6 1 ディスクリプタ表

ステップ2 フォーク カーネル 親プロセス 子プロセス 3 4 5 6 1 3 4 5 6 1 ディスクリプタ表 ディスクリプタ表

ステップ3,4 不要なFDを閉じる 1 1 3 3 4 親プロセス 4 カーネル 子プロセス 5 5 6 6 ディスクリプタ表 1 3 4 5 6 1 ディスクリプタ表 ディスクリプタ表

ステップ5 通信 カーネル 親プロセス 子プロセス 3 4 5 6 1 3 4 5 6 1 read(4, ...); 1 3 4 5 6 1 read(4, ...); write(5, ...); ディスクリプタ表 ディスクリプタ表

ステップ6 Close, Dup カーネル 親プロセス 子プロセス 3 4 5 6 1 3 4 5 6 1 read(0, ...); 1 3 4 5 6 1 read(0, ...); write(1, ...); ディスクリプタ表 ディスクリプタ表

不要なFDは切ってもよい カーネル 親プロセス 子プロセス 3 4 5 6 1 3 4 5 6 1 read(0, ...); 1 3 4 5 6 1 read(0, ...); write(1, ...); ディスクリプタ表 ディスクリプタ表

例 // pipe2.c main(int argc, char* argv[]){ // ps –ef | grep kaiya とやってることは同じ int pipes[2]; pid_t pid; if(pipe(pipes)<0) exit(1); if((pid=fork())==0){ // in child for writing close(pipes[0]); // close read close(1); dup(pipes[1]); execl("/bin/ps", "ps", "-ef", NULL); }else if(pid>0){ // in parent for reading close(pipes[1]); // close write close(0); dup(pipes[0]); execl("/bin/grep", "grep", "kaiya", NULL); }

簡易プロセス間通信 popen, pclose関数を使って,pipeを直接使わずに,簡単なフィルタを生成することができる. プログラムの処理結果を特定の他プログラムに入力したり, 特定の他プログラムの結果からデータを読んだりする場合,簡単にプログラムが書ける.

例 // popen1.c psの結果を読み,それの一部を抜き出して,cat –nに出力する. main(int argc, char* argv[]){ FILE* fp; FILE* ofp; char buf[100]; if((fp=popen("/bin/ps -ef", "r"))==NULL) exit(1); if((ofp=popen("/bin/cat -n", "w"))==NULL) exit(2); while(fgets(buf, 100, fp)!=NULL){ int pid; char name[100]; if(sscanf(buf, "%s %d", name, &pid)==2){ fprintf(ofp, "%d %s\n", pid, name); } fclose(ofp);