* セマフォの使い方 [#fee4c59d]

Linuxで、C言語を用いてセマフォを活用する方法を、記述します。

セマフォとは、プロセスやスレッドの同時実行を制御するための、OSで用意された機構です。あらかじめ同時実行できる数を指定し、それをセマフォの値の初期値とします(初期値が1の場合は、ほぼミューテックスと等しい動作になります)。セマフォによって同時実行が制限される処理を実行する場合、プロセスはセマフォから実行権を貰います。これをP操作と言います。逆に実行権を返すことをV操作と言います、もし他のプロセスによって、全ての実行権が取られていた場合は、他のプロセスのV操作により、自プロセスがP操作が出来るようになるまで待ちます。

ちなみにLinuxには、SystemVとPOSIXのセマフォがあり、両者は別物ですので、注意して下さい。両者の差異は勉強中です。(プロセス単位、スレッド単位?)

以下の例は、acceptor内で任意の数の子プロセスを生成し、子プロセスがtransport内の処理を実行するものです。transport内の処理を逐次処理とするために、セマフォを使用しております。

 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/sem.h>
 
 #define PROCESS_MAX 5
 
 // semctlのコマンド用(開発者がソース内で定義しなくては駄目)
 union semun {
     int val;
     struct semid_ds *buf;
     unsigned short *array;
     struct seminfo *_buf;
 };
 
 void transport(int sem) {
     int res = 0;
     struct sembuf semb; // semop へ渡す設定内容の構造体
 
     semb.sem_num = 0;
     semb.sem_op = -1; // セマフォから権限を取得する
     semb.sem_flg = SEM_UNDO;
     res = semop(sem, &semb, 1);
 
     printf("tansport started\n");
     sleep(2);
     printf("tansport finished\n");
 
     semb.sem_num = 0;
     semb.sem_op = 1; // セマフォから得た権限を返還する
     semb.sem_flg = SEM_UNDO;
     res = semop(sem, &semb, 1);
 }
 
 void acceptor() {
     int res = 0;
     int i = 0;
     int sem;
     union semun semcmd; // semctl へ渡すコマンド用の共用体
 
     // セマフォを取得する
     sem = semget(IPC_PRIVATE, 1, 0666|IPC_CREAT);
 
     // セマフォに初期値を設定する(この値が、同時実行を許可する数になる)
     semcmd.val = 1;
     res = semctl(sem, 0, SETVAL, semcmd);
 
     while(i < PROCESS_MAX) {
         int pid;
 
         pid = fork(); // fork システムコールで、子プロセス生成
         switch(pid) {
             case 0: // 子プロセスの場合に実行する
                 transport(sem);
                 exit(0); // 子プロセスはここで終了する
             break;
         }
         // 親プロセスは処理を続行する
 
         i++;
     }
 }
 
 int main() {
     acceptor();
 }

本来は、acceptorの中で、前の子プロセスによるtransport処理が終了するまで、fork()システムコールの実行を待ち合わせるようにしたかったのですが、セマフォ操作を実行するプロセスが異なると、様々な制約が発生し、難しくなります。ある意味セマフォは一般的な同期処理を行なうために、安全な手法を提供してくれるのかもしれませんが、少し凝ったことを考えると、使いにくい印象を受けました。それこそ、共有メモリを使った方が、開発者の管理責任は増すものの、明らかに自由度は高くなります。

とにかく今回二日ほど試行してみて感じたことは、セマフォは特定処理の排他制御以外への利用は、なかなか難しいということです。

---- 
** 履歴 [#vace5ac2]
- 2005/09/04 初版

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS