next up previous contents
Next: 共有メモリ Up: プロセス間通信をする Previous: メッセージ

セマフォ

セマフォは主にプロセス間で同期を取るために使われる技術です。辞書によ るとsemaph oreとは鉄道の腕木信号機だそうです。信号が赤の間待っていて、 青になったら出発するといった使い方になるわけです。セマフォの操作のため のシステムコールは3つ用意されています。まずセマフォを用意します。

        #include        <sys/types.h>

        #include        <sys/ipc.h>

        #include        <sys/sem.h>



        int     semid;

        semid = semget( key, nsems, semflag );

ここでkeyはセマフォを共有するプロセスの間でしめしあわせた数字です。 nsemsは割り付けられるセマフォの数、semflagはアクセス許可及び割付方法を 指定するフラッグです。アクセス許可は下9ビットを、通常のファイルアクセ スのように使います。さらにIPC_ALLOCビットを立てるとすでに割り付けられ たセマフォを返します。なければエラーになります。IPC_CREATビットを立て るとなければあらたに割り付けられます。IPC_EXCLビットを立てるとすでに割 り付けられていればエラーになります。エラーの場合semidに-1が返されます。 例えば次のようになります。

        semid = semget( 23456, 1, IPC_CREAT | 0666 );

この例ではキーを23456として一つのセマフォをIPC_CREATで新たに割り付け、 誰にでもアクセスを許します。(0666)

ここまででセマフォは確保しました。次にそのセマフォを使って作業をしま す。各々のセマフォは値を持っています。プロセスの間でその値を増やしたり へらしたりする一方でそのセマフォ値がある値になるのを待ちます。複雑な作 業をセマフォの集合に対して行なえるように操作のリストを渡してやるので少 し呼出し方が複雑です。

        struct sembuf semops[1];



        semops[0].sem_num = 0;  /* 最初のセマフォ */

        semops[0].sem_op = -1;  /* セマフォ値から1引いて待つ*/

        semops[0].sem_flg = 0;

        st = semop( semid, semops, 1 );

semidはsemgetで確保したセマフォです。sem_opが操作を表します。0より大き な数を与えると単にその値をセマフォ値に加えて戻ります。0より小さな数を 与えるとその数をセマフォ値に加え(負の数を加える)、そのセマフォ値が0以 上になるのを待ちます。sem_opが0のときはセマフォ値が0になるのを待ちます。 最後の1はsemopsに定義されている操作の数で、今の例では1ということになり ます。この操作ではセマフォ値から1を引いてほかの誰かが1足してくれるのを 待ちます。

現在のセマフォ値を調べたり、セマフォ値を待ち状態に入らずに設定したり、 セマフォ待ちのプロセスを調べたりセマフォを削除したりするためのシステム コールはsemctlです。

        st = semctl( semid, semnum, cmd, arg );

ここでsemidは確保しているセマフォ、semnumはその内何番目のものか、cmdは 操作を表し、

        GETVAL  現在のセマフォ値を返す。

        SETVAL  セマフォ値をセットする。

        GETPID  最後にセマフォを操作したプロセスのPIDを返す。

        GETNCNT 現在セマフォ待ちのプロセスの数を返す。

        GETZCNT セマフォが0になるのを待っているプロセスの数を返す。

などがあります。argは操作cmdの値によって決められた型の引数です。SETVAL の時は設定されるべき値を整数で与えます。上の例でセマフォが0になるのを 待っているプロセスがいます。

        if( semctl( semid, 0, SETVAL, 0 ) == -1 )

        { /* 戻り値が-1の時はエラー */ }

現在のセマフォの値を調べるには

        semval = semctl( semid, 0, GETVAL, 0 );

で調べることができます。

セマフォの状態もメッセージと同じようにipcsで見ることが出来ます。また ipcrm -sでセマフォを削除することも出来ます。セマフォ待ちのプロセスはセ マフォが削除されるとエラーとなってシステムコールから戻ります。プロセス がシグナルを受け取ったときも同じです。

セマフォの使い方としては例えばプロセスAが書き込みをし、プロセスBとC が読みだすといった場合が考えられます。まず初期状態で読み出し許可セマフォ は-2に設定されます。BとCは読み出し許可セマフォが0になるのを待ちます。A はBやCが作業を開始できるようになると、読み出し許可セマフォを0にし、読 み出し完了セマフォから2を引いて待ちます。BとCはそれぞれ実行を開始し、 完了するとそれぞれ読み出し完了セマフォに1を加え、読み出し許可セマフォ から1を引いて次の読み出し許可を待ちます。任意の数のプロセスの間でこう いった作業が可能です。



next up previous contents
Next: 共有メモリ Up: プロセス間通信をする Previous: メッセージ



Kinya Hibino
Sun Jan 14 21:36:40 JST 1996