割 込 み(2) オペレーティングシステム No.6 プログラムの記述(1) 制御プログラムを記述する言語 Cの一部 プログラムの記述(2) a=b; b(一般に式)の値を計算して, 変数aに格納する プログラムの記述(3) if (条件) { … } 条件が成立する(真)場合のみ, { … }の部分を実行する 条件 a = = b aとbが等しいか? 条件 c cが真か?(cが正しいか?) プログラムの記述(3) while (条件) { … } ①条件を調べる ②成立する場合は,{ … }を実行してから①に戻 る ③成立しない場合は,この先に進む 条件が成立する間(正しい間), { … }を繰り返し実行する 割込み処理の例 ちょっと難しいかも知れないが, 雰囲気は分かって欲しい 印刷処理 プリンタの制御 想定するプリンタ CPUがプリンタの速度に合わせると効率が悪くなる 1文字ずつ印字 現在あるかどうかは不明 割込みで,どのようにこのギャップを埋めるのか!? 過去にはあった(使ったことがある) プリンタの印字速度は遅いが,CPUの計算速度 は速い プリンタの使い方 プログラムから,印字する1文字分のデータ(文 字コード)をプリンタに送る プリンタに,(先に送ったデータの)印字開始を指 示する 印字終了までに時間がかかる! 注意 プリンタが印字動作中に印字データを送ることは できない(送っても無視される) プ リ ン タ の 制 御 命 令(1) send(PRINTER, date) PRINTERにdata(データ,印字する文字の文 字コード)を送る手続き 複数のプリンタが接続されている場合は, PRINTERの値により区別する。 しかし,この例ではプリンタは1台だけなので, PRINTERは無視してかまわない。 プ リ ン タ の 制 御 命 令(2) start(PRINTER) PRINTERに既に送ってあるデータの 印字を開始させる手続き 印字には時間がかかるが,その終了を 待たずに手続きの呼び出し元に戻る startの次を実行しているときは, まだ印字中である プ リ ン タ の 制 御 命 令(3) busy(PRINTER) PRINTERが動作中,つまり印字中なら真 (true), そうでないなら偽(false)を返すプリンタの状 態を調べるための関数 プリンタは動作中にsendでデータを送られて も受け取ることができないので,この関数で 状態をチェックする 割込みを用いないプログラム 印字データdata用意 send(PRINTER, data); start(PRINTER); while( busy(PRINTER) ) { ; } 印字データをプ リンタに送る このような部分が, プログラム中に たくさんある! 次の印字データ用意 プリンタがbusyの間(印字中 以下同様 の間),何もしないことを繰り 返す(印字の終了を待つ) 印字終了後,先に進む start終了直後は, プリンタは印字動作 中 プログラムとプリンタの動作 while( busy(PRINTER) ) { ; } プリンタの動作中は,プログラムの実行が実質上止まる 割 込 み の 利 用(1) 印字終了で,プリンタが割込みをかけられる 外部割込み “プリンタの印字終了”という事象により,割込 み発生 利用者プログラムを中断 割込み処理プログラムの実行 その終了後,中断していた利用者プログラム を再開 bufferが“空”かどうか 割 込 み の 利 用(2) YESなら“空”,NOなら“印字データがある” 2つのプログラムから読み書きできる変数 empty:YESまたはNO(初期値はYES) buffer:印字データを一時的に格納 割 込 み の 利 用(3) emptyがNOであったら, 何もしないことを繰り返し続ける。 そのうちにemptyがYESになり,先 に進む 利用者プログラム 印字データdata用意 while(empty = = NO) { ; } buffer = data; empty = NO; if(not busy(PRINTER)) { send(PRINTER, buffer); start(PRINTER); empty = YES; } プリンタがbusyでなけ れば… (印字中でなければ) プリンタは動作中である が,プログラムは先に進 む 割 込 み の 利 用(4) プログラム中に, 青枠部分がたくさんあ る 1文字目 2文字目 3文字目 割 込 み の 利 用(5) 割込み処理プログラム(利用者プログラムとは全 く別のところにある – OSの一部) if(empty = = NO) { send(PRINTER, buffer); start(PRINTER); empty = YES; } 割 込 み の 利 用(6) 利用者プログラム while(empty = = NO) { ; } buffer = data; empty = NO; if(not busy(PRINTER)) { send(PRINTER, buffer); start(PRINTER); empty = YES; } 1文字目が用意できた empty は YES 印字データをbufferに emptyをNOに プリンタは動作中でないから, busyではない bufferのデータを送り, プリンタをスタート emptyをYESに 2文字目の用意を始める (プリンタは印字中) 割 込 み の 利 用(7) プリンタが1文字目を印字中に, 2文字目の用意ができたとする 割 込 み の 利 用(8) 利用者プログラム while(empty = = NO) { ; } buffer = data; empty = NO; if(not busy(PRINTER)) { send(PRINTER, buffer); start(PRINTER); empty = YES; } 2文字目が用意できた empty は YES 印字データをbufferに emptyをNOに プリンタは動作中なので, 実行しない 2文字目はbufferに入れたまま, 3文字目の用意 (プリンタは1文字目を印字中) 割 込 み の 利 用(9) 1文字目の印字 終了の割込み 割 込 み の 利 用(10) if(empty = = NO) { send(PRINTER, buffer); start(PRINTER); empty = YES; } 割込み処理プログラム emptyはNO buffer中のデータ(2文字目)を プリンタに送る プリンタをスタート emptyをYESに 3文字目を用意している 割り込まれたプログラムを再開 割 込 み の 利 用(11) CPU(プログラム)とプリンタが同時に動作 効率がよくなる 一言でまとめると CPU→プリンタ→CPU→プリンタ→… と交互に動作するのではなく, プリンタの動作中も,CPUは動作(処理)すること により,CPUを無駄なく使う 補 足 とりあえず,今までのことを理解して欲しい 補 足(1) 何文字目かの印字データが用意できたとき emptyがNOであったらどうなるか? buffer中に,直前の文字 さらにその前の文字をプリンタが印字中 つまり,印字される文字がたまってしまってい る そのうちに,印字終了の 実際には,このような状態になることがほと 割込みが発生する! んどである 補 足(2) emptyがNOなので,ここで待つ! while(empty = = NO) { ; } buffer = data; empty = NO; if(not busy(PRINTER)) { send(PRINTER, buffer); start(PRINTER); empty = YES; } そのうちに,印字終了割込 みが発生する if(empty = = NO) { send(PRINTER, buffer); start(PRINTER); empty = YES; } emptyがYESになる 補 足(3) bufferを配列 参照 補足(1) 利用者プログラム中の印字関係の部分を手続 きにする 割込み禁止部分が必要 補 足(4) 割込みを用いないプログラムの変更 印字データdata用意 while( busy(PRINTER) ) { ; } send(PRINTER, data); start(PRINTER); 次回 割込み発生のタイミングにより,正しく処理 できなくなる場合がある クリティカルレース 際どい部分(クリティカルセクション)
© Copyright 2024 ExpyDoc