信号の操作


前の記事の信号灯の操作に関する問題と,構造体sumbufについて[url]から節選した.http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/index.html[/url]
Linux環境プロセス間通信(四)鄭彦興([email protected])国防科学大コンピュータ学院の記事で説明できます
=======================================
四、操作信号
メッセージ・キューの操作には、次の3つのタイプがあります.
1、信号の点灯または作成
メッセージキューの作成と開くのとほぼ同じで、詳細は説明しません.
2、信号値操作
linuxは、共有リソースの解放および占有に対応する信号ランプの値を増加または減少させることができる.詳細については、後述するsemopシステム呼び出しを参照してください.
3、信号の属性を取得または設定する:
システム内の各信号セットはstruct sem_に対応するarray構造は、信号ランプセットの様々な情報を記録し、システム空間に存在する.この信号セットの様々な情報および属性を設定、取得するために、ユーザ空間には、それに対応する重要な連合構造、すなわちunion semunがある.

連合semunデータ構造の各メンバーの意味は付録2を参照
信号灯API
1、ファイル名からキー値
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok (char*pathname, char proj);

パスpathnameに対応するキー値を返します.具体的には、「Linux環境プロセス間通信(3):メッセージキュー」を参照してください.
2、linux特有のipc()呼び出し:
int ipc(unsigned int call, int first, int second, int third, void *ptr, long fifth);
パラメータcallが異なる値をとると、対応する信号灯の3つのシステムが呼び出されます.
callがSEMOPである場合、int semop(int semid,struct sembuf*sops,unsigned nsops)呼び出しに対応する.
callがSEMGETである場合、int semget(key_t key,int nsems,int semflg)呼び出しに対応する.
callがSEMCTLの場合、int semctl(int semid,int semnum,int cmd,union semun arg)呼び出しに対応する.
これらの呼び出しは後述する.
注:本人はシステム呼び出しipc()を主張するのではなく、システムVまたはPOSIXプロセス間通信APIを採用する傾向がある.理由はLinux環境プロセス間で通信されています(3):メッセージキューに表示されます.
3、システムV信号API
システムVメッセージキューAPIは3つしかありません.使用時にはいくつかのヘッダファイルを含める必要があります.
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

1)int semget(key_t key, int nsems, int semflg)
パラメータkeyはftokから得られたキー値であり、msgget()のkeyと同様に使用される信号セットを一意に識別する.パラメータnsemsは、オンまたは新しく作成された信号セットが信号を含む数を指定します.semflgパラメータはいくつかのフラグビットです.パラメータkeyとsemflgの値、および既存の信号セットをいつ開くか、またはmsgget()の対応する部分と同じ新しい信号セットを作成するかは、説明しない.
この呼び出しは、健値keyに対応する信号ランプセット記述語を返す.
コールバック:信号セット記述語が正常に返されました.そうでなければ-1が返されます.
注意:keyが表す信号が既に存在し、semgetがIPC_を指定している場合CREAT|IPC_EXCLフラグは、パラメータnsemsが元の信号の数と等しくなくてもEEXISTエラーを返します.semgetがIPCのみを指定した場合CREATフラグは、パラメータnsemsが元の値と一致する必要があり、後述のプログラムインスタンスでさらに説明します.
2)int semop(int semid, struct sembuf *sops, unsigned nsops);
semidは信号ランプセットIDであり、sopsが配列を指す各sembuf構造は、特定の信号ランプ上の動作を描画する.nsopsはsopsが配列を指すサイズです.
sembuf構造は以下の通りである.
struct sembuf {
unsigned short sem_num; /* semaphore index in array */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};

sem_numは信号セットの信号ランプに対応し、0は第1の信号ランプに対応する.sem_flg取得可能IPC_NOWAITおよびSEM_UNDOの2つのマーク.SEM_が設定されている場合UNDOフラグは、プロセスが終了すると、対応する操作がキャンセルされます.これは比較的重要なフラグビットです.フラグビットが設定されている場合、プロセスが共有リソースを解放せずに終了すると、カーネルが解放されます.信号にフラグが設定されている場合は、カーネルにsem_が割り当てられます.undo構造は、後でリソースが安全に解放されることを確保するために記録される.実際、プロセスが終了すると、占有は解放されますが、信号値は変更されません.この場合、信号値はリソース占有の実際の状況ではありません.この場合、問題の解決はカーネルによって行われます.これはゾンビプロセスに似ています.プロセスは終了し、リソースも解放されましたが、カーネルプロセステーブルには記録が残っています.この場合、親プロセスがwaitpidを呼び出して問題を解決する必要があります.
sem_opの値が0より大きく、0に等しく、0未満であることはsem_を決定するnum指定の信号による3つの操作.具体的にはlinux対応マニュアルページを参照してください.
ここで強調する必要があるのは、semopが複数の信号灯を同時に操作し、実際の応用では、複数のリソースの申請または解放に対応することである.semopは操作の原子性を保証する点が特に重要である.特に多種の資源の申請にとって、一度にすべての資源を獲得するか、申請を放棄するか、いかなる資源を占有しない状況で待ち続けるか、このようにして、一方で資源の浪費を避けた.一方、共有リソースの申請によるプロセス間のデッドロックは回避される.
信号ランプの現在値は、対応するリソースが現在利用可能な数を記録する.sem_op>0対応プロセスsem_を解放するop数の共有リソース;sem_op=0は、共有リソースが切れたかどうかのテストに使用できます.sem_op<0はプロセスが申請する-sem_に相当するop個の共有リソース.操作の原子性を連想しても,このシステム呼び出しがいつ正常に返され,いつ睡眠待ちになるかは理解に難くない.
コールバック:0が正常に返されました.そうでなければ-1が返されます.
3) int semctl(int semid,int semnum,int cmd,union semun arg)
このシステム呼び出しは信号灯に対する各種制御操作を実現し、パラメータsemidは信号灯セットを指定し、パラメータcmdは具体的な操作タイプを指定する.パラメータsemnumはどの信号灯に対して操作するかを指定し、いくつかの特殊なcmd操作にのみ意味がある.argは、信号情報を設定または返すために使用される.
このシステム呼び出しの詳細は、パラメータcmdで指定できる操作のみを示すマニュアルページを参照してください.
IPC_STAT
信号情報を取得するarg.bufが戻る;
IPC_SET
信号情報を設定、argに保存する.buf(manpageで設定できる情報を示しています);
GETALL
すべての信号の値を返し、argに保存する.arrayでは、パラメータsennumは無視されます.
GETNCNT
semnumが表す信号を待つ値が増加したプロセス数を返します.semnumが表す信号を待つプロセスが現在どれだけあるかに相当します.
GETPID
semnumで表される信号ランプに対してsemop動作を実行する最後のプロセスIDを返す.
GETVAL
semnumが表す信号の値を返します.
GETZCNT
semnumが表す信号を待つ値が0になるプロセス数を返す.
SETALL
argを通過する.arrayはすべての信号の値を更新します.同時に、本信号セットに関連するsemid_を更新するds構造のsem_ctimeメンバー;
SETVAL
semnumが表す信号の値をargとする.val;