1. セマフォとは 他の通信リソースを制御することで、プロセス通信を実現するためのカウンターです。このプロセス中のデータの相互排除、同期などを担当します。相互排他とは、同じ期間中に A と B の 1 つのプロセスだけが実行されることを意味します。同期します。つまり、処理 A が完了すると、次に処理 B が完了するという順序があり、実行には順序があります。
2.動作原理
2つの動作モード、P動作とV動作。
P 操作 (つまり、リソースを申請し、セマフォが 1 つ減ります)
V 操作 (リソースを解放し、セマフォが 1 つ増加します)
3. semid
ipcrm を表示します - s id idの削除
4. 主な関数
shmget セマフォの作成
shmctl 削除
shmop P/V演算
関数プロトタイプ: int semop(int sem_id,struct sembuf *sops,size_t nsops);
sem_id作成されましたshmget 関数を使用して
struct sembuf *sops パラメータ sops は構造体配列を指し、各 sembuf 構造体は信号操作に対応します。構造は以下の通りです
struct sembuf { unsigned short sem_num;//sem_num是信号集中的索引,0代表第一个,1,代表第二个。。。 short sem_op; //操作类型,1 -->V操作,-1-->P操作 short sem_flg; //操作标志 };
nsops は SOPS の数です
~~ ~~~~~~~~~~ ~~~~************ Man 関数名は関数の使用法を表示できます**** ****** **~~~~~~~~~~~~~~~~~~~
5. コード実装
comm.h
#pragma once #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> #define _PATH_ "." #define _PROG_ID_ 0x6675 union semun { int val; struct semid_ds *buf; unsigned short *array; struct seminfo *__buf; }; int creatSem(int nsems); int get_Sem(); int initSem(int sem_id,int Which); int destroySem(int sem_id); int V_Sem(int sem_id,int which); int P_Sem(int sem_id,int which); static int op_Sem(int sem_id,int op,int which);
#include"comm.h" int creatSem(int nsems) { key_t _key=ftok(_PATH_,_PROG_ID_); if(_key<0) { perror("ftok"); return -1; } umask(0); int sem_Flg=IPC_CREAT|IPC_EXCL|0666; int sem_id=semget(_key,nsems,sem_Flg); if(sem_id<0) { perror("semget"); return -1; } return sem_id; } int get_Sem() { key_t k=ftok(_PATH_,_PROG_ID_); return semget(k,0,0); } static int op_Sem(int sem_id,int op,int which) { struct sembuf sem; sem.sem_num=which; sem.sem_op=op; sem.sem_flg=0; return semop(sem_id,&sem,1); } int initSem(int sem_id,int Which) { union semun _semum; _semum.val=1; int ret= semctl(sem_id,Which,SETVAL,_semum); if(ret==-1) { perror("semctl"); return ret; } return ret; } int P_Sem(int sem_id,int which) { int ret=op_Sem(sem_id,-1,which); if(ret==-1) { perror("p_sem"); return -1; } return ret; } int V_Sem(int sem_id,int which) { int ret=op_Sem(sem_id,1,which); if(ret==-1) { perror("V_Sem"); return ret; } return ret; } int destroySem(int sem_id) { int ret=semctl(sem_id,0,IPC_RMID,NULL); if(ret==-1) { perror("semtrl"); return -1; } return ret; }
#include"comm.h" int main() { int sem_id=creatSem(1); initSem(sem_id,0); pid_t id=fork(); if(id<0) { perror("for"); return -1; } else if(id==0) { int sem_id=get_Sem(); while(1) { P_Sem(sem_id,0); printf("A"); fflush(stdout); sleep(1); printf("A"); fflush(stdout); sleep(2); V_Sem(sem_id,0); } }else { while(1) { P_Sem(sem_id,0); printf("B"); fflush(stdout); sleep(1); printf("B"); fflush(stdout); sleep(1); V_Sem(sem_id,0); } waitpid(id,NULL,0); } }