ミューテックスとセマフォはどちらもOS排他制御を実現する機能
セマフォ
※以下に記載した"プロセス"は、"スレッド"に読み替え可能。
・共有資源にアクセスできるプロセス数を管理するカウンタ(カウンティングセマフォ)
・P操作で1減算、V操作で1加算
・値を10に設定すれば、10個のプロセスが同時にアクセス可能。
・値をゼロに設定すれば、他プロセスは1以上になるまでプロックされる為、ミューテックスと同様にロックとしても利用可能。(バイナリセマフォ)
・この動作を複数のプロセスの同期処理(待ち合わせ)にも利用できる。
→待ち合わせ=同時実行される複数プロセス間での処理タイミングの調整
★重要★
"共有資源"は複数プロセス間でメモリ上で共有される変数等。ファイルではない。
・スレッドの場合、スレッド間の共有変数
・プロセスの場合、名前付きセマフォ(仮想ファイルシステム上に生成)
セマフォ利用方法
Linuxシステムコール、セマフォの使い方
・セマフォにはキーがある。
・複数のプロセス間でキーによって、生成済みのセマフォを特定できる。
・セマフォはリスト(集合)で、1つのセマフォの中に複数のセマフォカウンタを定義できる。
上記参考URLのサンプルコードの処理内容
seminit.c
・ftok()関数で任意のファイルから、ftok()関数でセマフォキーを生成
・生成したキーでセマフォを定義。(要素数は1個だけのセマフォ)
semproc.c
・seminit.cで生成したセマフォでロックをかける。成功したら、ユーザー入力を受けてロックを解除。
seminit.cを実行して、1個目のターミナルでsemproc.cを実行するとセマフォでロックがかかる。2個目のターミナルでsemproc.cを実行するとロック取得待ちになる。
★プロセスはOSのセマフォ機能を使うことで、プロセス間でのロックによる同期処理ができる★
コマンドでの動作確認
カウンタ1個のセマフォを生成(ipcmk) & 生成確認(ipcs) & 削除(ipcrm)
$ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems $ ipcmk -S 1 Semaphore id: 0 $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0x7890f5a3 0 ec2-user 644 1 $ ipcrm -s 0 $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems $
カウンタ10個のセマフォを生成(ipcmk) & 生成確認(ipcs) & 削除(ipcrm)
$ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems $ ipcmk -S 10 Semaphore id: 1 $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0xdec22ed2 1 ec2-user 644 10 $ ipcrm -s 1 $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems $
セマフォメモ
kernelパラメタでセマフォ制限の設定あり。
# sysctl kernel.sem kernel.sem = 32000 1024000000 500 32000 #
パラメタの意味は以下URL参照
2.1.1 システムパラメーターのチューニング【Linux】
※上記URLより引用
kernelパラメタのセマフォ制限の確認
システム全体のセマフォ識別子の上限(引数4個目)超え時の動作
# sysctl kernel.sem kernel.sem = 32000 1024000000 500 32000 # sysctl -w kernel.sem="32000 1024000000 500 2" kernel.sem = 32000 1024000000 500 2 # ipcmk -S 1 Semaphore id: 1 # ipcmk -S 1 Semaphore id: 2 # ipcmk -S 1 ipcmk: create semaphore failed: No space left on device # ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0x737eced2 1 root 644 1 0x496e3ae4 2 root 644 1 #
# sysctl kernel.sem kernel.sem = 32000 1024000000 500 32000 # ipcmk -S 32000 Semaphore id: 3 # ipcmk -S 32001 ipcmk: create semaphore failed: Invalid argument # ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0xb01d3240 3 root 644 32000 #
システム全体のセマフォカウンタ数の上限(引数2個目)超え時の動作
# sysctl -w kernel.sem="32000 32000 500 32000" kernel.sem = 32000 32000 500 32000 # ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems # ipcmk -S 32000 Semaphore id: 4 # ipcmk -S 1 ipcmk: create semaphore failed: No space left on device #
上記制限はシステム全体の制限。
なので、特定ユーザーが大量消費し制限到達したら、他ユーザーは使えなくなる。
ただし、rootユーザーはセマフォを削除できる。
他ユーザーは別ユーザーのセマフォは削除はできなさそう。
$ id uid=1001(hoge) gid=1001(hoge) groups=1001(hoge) $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0x44564196 5 root 777 1 0x1833097e 6 ec2-user 644 1 0x96432e7c 7 ec2-user 777 1 $ ipcrm -s 5 ipcrm: permission denied for id (5) $ ipcrm -s 7 ipcrm: permission denied for id (7) $
参考
Man page of SEM_OVERVIEW
→名前付きセマフォの説明あり。「2 つのプロセス間で同じ名前のセマフォ に対し操作を行うことができる。」
multiprocessing --- プロセスベースの並列処理 — Python 3.10.6 ドキュメント
threading --- スレッドベースの並列処理 — Python 3.10.6 ドキュメント
→multiprocessingとthreadingどちらにもセマフォ操作のメソッドあり。セマフォはマルチスレッドだけでなく、マルチプロセス間でも利用可能。
マルチスレッド・プログラミングの道具箱
→ミューテックスとセマフォの違い。ロック所有権の概念の有無。※以下引用