セマフォによる排他制御 セマフォによる排他制御 排他制御の目的 セマフォ(Semaphore) - 排他制御のアナロジー 排他制御のシステム概要 排他制御のプロセスシーケンス セマフォの操作 排他制御の実施例 セマフォの基本操作プログラミング: セマフォオブジェクト(集合)の生成 セマフォの基本操作プログラミング: セマフォオブジェクトの初期化 セマフォの基本操作プログラミング: セマフォのロック セマフォの基本操作プログラミング: セマフォのアンロック 事例: forkした子プロセス間の排他制御 セマフォによる排他制御 排他制御の目的 Critical Sectionの保護 Critical Section コンピュータ資源を、複数のプロセスが同時に利用するこ とを回避(=排他制御)しなければならないプログラムの 部分 コンピュータ資源(排他制御の対象となりうるあらゆる資源) オブジェクト CPU ファイル メモリ ネットワーク 周辺装置(ディスプレイ等) 外部環境(制御対象システム等) セマフォによる排他制御 セマフォ(Semaphore) - 排他制御のアナロジー Semaphore 腕木信号 Critical Section セマフォによる排他制御 排他制御のシステム概要 プロセスA,B,Cは、同じ鍵を持っている ★セマフォの動作原理 •セマフォから値を引いた結果 が、0以下になると、プロセス がスリープする。また、結果 が0または0以上になると自動 的にスリープから脱する。 •セマフォのロックは値から-1 する。 •セマフォのロック解除は値に +1する。 ロック操作 プロセスA プロセスB ロック操作 semget(); semop(); { //critical section } semget(); アンロック操作 semop(); アンロック操作 { //critical section } semop(); semop(); 初期値 プロセスC (初期設定) セマフォ semget(); 1 semctl(); カーネル 1: 使用中 0: 未使用 セマフォによる排他制御 排他制御のプロセスシーケンス プロセスA,B,Cは、同じ鍵を持っている プロセスA ★動作原理 •セマフォから値を引いた結果 が、0以下になると、プロセス がスリープする。また、結果 が0または0以上になると自動 的にスリープから脱する。 •セマフォのロックは値から-1 する。 •セマフォのロック解除は値に +1する。 使い終わったら1増やす (アンロック) プロセスA 使う時 1減らす (ロック) -1 A使用中 Critical Section +1 セマフォ セマフォ セマフォ セマフォ セマフォ 1 0 0 1 0 -1 プロセスC (初期設定) プロセスB 初期値=1 待ち解除 semget(); semctl(); 使う時1減らす (ロック) B使用中 Critical Section セマフォによる排他制御 セマフォの操作 プロセスA,B,Cは、同じ鍵を持っている プロセスA ★操作 •セマフォオブジェクトの生成 •鍵、セマフォ数 •初期化 •セマフォ値を設定する •アンロック •セマフォ値を増やす •ロック •セマフォ値を減らす 使い終わったら1増やす (アンロック) プロセスA 使う時 1減らす (ロック) -1 A使用中 Critical Section +1 セマフォ セマフォ セマフォ セマフォ セマフォ 1 0 0 1 0 -1 プロセスC (初期設定) プロセスB 初期値=1 待ち解除 semget(); semctl(); 使う時1減らす (ロック) B使用中 Critical Section セマフォによる排他制御 排他制御の実施例 プロセスA,B,Cは、同じ鍵を持っている プロセスA ★実施例 •セマフォ値=1の時 •プロセスはセマフォ値を 0にし、資源を使用する (即ち、クリティカルセク ションを実行する。) •セマフォ値=0の時 •プロセスはセマフォ値を 変更せず、セマフォ値が 0になるまで待つ 使い終わったら1増やす (アンロック) プロセスA 使う時 1減らす (ロック) -1 A使用中 Critical Section +1 セマフォ セマフォ セマフォ セマフォ セマフォ 1 0 0 1 0 -1 プロセスC (初期設定) プロセスB 初期値=1 待ち解除 semget(); semctl(); 使う時1減らす (ロック) B使用中 Critical Section セマフォによる排他制御 セマフォの基本操作プログラミング: セマフォオブジェクト(集合)の生成 プロセスA,B,Cは、同じ鍵を持っている //セマフォオブジェクトの生成 int semid; key_t semkey; semkey = ftok("seminit", 'a'); semid = semget(semkey, 1, IPC_CREAT|0666); if(semid==EOF) { printf("%s\n","ERR"); exit(0); } プロセスA 使い終わったら1増やす (アンロック) プロセスA 使う時 1減らす (ロック) -1 A使用中 Critical Section +1 セマフォ セマフォ セマフォ セマフォ セマフォ 1 0 0 1 0 -1 プロセスC (初期設定) プロセスB 初期値=1 待ち解除 semget(); semctl(); 使う時1減らす (ロック) B使用中 Critical Section セマフォによる排他制御 セマフォの基本操作プログラミング: セマフォオブジェクトの初期化 プロセスA,B,Cは、同じ鍵を持っている プロセスA //セマフォに初期値1を書き込 む if((semctl(semid,0,SETVAL,1)) == EOF) { printf("%s\n","ERR"); exit(0); } 使い終わったら1増やす (アンロック) プロセスA 使う時 1減らす (ロック) -1 A使用中 Critical Section +1 セマフォ セマフォ セマフォ セマフォ セマフォ 1 0 0 1 0 -1 プロセスC (初期設定) プロセスB 初期値=1 待ち解除 semget(); semctl(); 使う時1減らす (ロック) B使用中 Critical Section セマフォによる排他制御 セマフォの基本操作プログラミング: セマフォのロック プロセスA,B,Cは、同じ鍵を持っている //排他処理の開始するためのロック //自分よりも先にロックされていた場合に //はロック解除されるまでスリープする プロセスA void lock(int semid) 使う時 { 1減らす struct sembuf sb[1]; (ロック) sb[0].sem_num=0; sb[0].sem_op=-1; sb[0].sem_flg=0; セマフォ if(EOF==semop(semid,sb,1)) 1 { printf("%s\n","lock ERR"); exit(1); } } プロセスC (初期設定) プロセスA 使い終わったら1増やす (アンロック) -1 A使用中 Critical Section セマフォ セマフォ セマフォ セマフォ 0 0 1 0 -1 プロセスB 初期値=1 待ち解除 semget(); semctl(); +1 使う時1減らす (ロック) B使用中 Critical Section セマフォによる排他制御 セマフォの基本操作プログラミング: セマフォのアンロック プロセスA,B,Cは、同じ鍵を持っている //排他処理の終了のためのロック解除 void unlock(int semid) プロセスA { 使う時 struct sembuf sb[1]; 1減らす sb[0].sem_num=0; (ロック) sb[0].sem_op=1; sb[0].sem_flg=0; if(EOF==semop(semid,sb,1)) { printf("%s\n","unlock ERR"); exit(1); } セマフォ } 1 プロセスA 使い終わったら1増やす (アンロック) -1 A使用中 Critical Section +1 セマフォ セマフォ セマフォ セマフォ 0 0 1 0 -1 プロセスC (初期設定) プロセスB 初期値=1 待ち解除 semget(); semctl(); 使う時1減らす (ロック) B使用中 Critical Section セマフォによる排他制御 事例: forkした子プロセス間の排他制御 • • • 3つの子プロセスを作成して排他処理を行う。 子プロセス1では文字Aを、子プロセス2では文字B を、子プロセス3では文字Cを、出力する。 各子プロセスは、ディスプレイの利用をクリティカル セクションとして保護し、排他制御する。 kishima@DdeDynabook-4 $ gcc sem_fork.c -o sem_fork sem_fork.c kishima@DdeDynabook-4 $ ./sem_fork AAAAAAAAAABBBBBBBBBBCCCCCCCCCC kishima@DdeDynabook-4 $
© Copyright 2025 ExpyDoc