頭文件:
sys/sem.h
查看:
ipcs
信號量獲取:
int semget(key,nsems,semflg);
key:
命名信號量。
IPC_PRIVATE 和 ftok()兩種方式。
nsems:
信號量數目。
非0——新建的信號量的數量。
0———獲取信號量(打開時填0)
semflg:
IPC_CREAT————————創建信號量,已存在時不出錯(創建無效)。
IPC_CREAT|IPC_EXEC——創建信號量,已存在時出錯。
IPC_CREAT|0644——————正常創建格式(後面爲mode格式)。
返回值:
非負整數——信號量標識
-1—————失敗
信號量操作:
int semop(int semid,struct sembuf* sops,size_t nsops);
semid:
信號量標識。
sops:
信號量結構體:
sem_nun——信號量下標,從0開始。
sem_flg——內核處理IPC_NOWAIT;0;SEM_UNDO(進程結束時,相應的操作將被取消;進程沒有釋放該信號量而終止時,操作系統釋放信號量)。
PV操作——P(等待)操作爲-1;V(發送)操作爲1。
nsops:
semops大小。
信號量控制:
int semctl(semid,nsem,cmd,……);
nsem:
信號量下標。
cmd:
SETVAL——設置信號量的值
GETVAL——獲取信號量的值
IPC_RMID——刪除信號量
代碼:
創建信號量:
#include <stdio.h>
#include <unistd.h>
#include <sys/sem.h>
int main(int argc,char* argv[]){
key_t key = ftok(argv[1],1);
if(-1 == semget(key,1,IPC_CREAT|0644)){
perror("semget err");
return 1;
}
}
刪除信號量:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/sem.h>
int main(int argc,char* argv[]){
key_t key = ftok(argv[1],1);
int semid;
if((semid = semget(key,0,O_RDWR))==-1){
perror("semget err");
return 1;
}
if(-1 == semctl(semid,0,IPC_RMID)){
perror("semctl err");
return 1;
}
}
親緣間信號量的創建和使用:
#include <stdio.h>
#include <stdlib.h>
#include <sys/sem.h>
#include <unistd.h>
void sem_p(int semid){
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = -1;
buf.sem_flg = 0;
semop(semid,&buf,1);
}
void sem_v(int semid){
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = 1;
buf.sem_flg = 0;
semop(semid,&buf,1);
}
union semun{
int val;
};
int main(int argc,char * argv[]){
int semid = semget(IPC_PRIVATE,1,IPC_CREAT|0644);
union semun un = {1};
if(-1 == semctl(semid,0,SETVAL,un)){
perror("semctl err");
return 1;
}
if(-1 == semid){
perror("semget err");
return 1;
}
fork();
int i=0;
for(;i<5;i++){
sem_p(semid);
printf("PID:%d,enter\n",getpid());
sleep(1);
printf("PID:%d,do something\n",getpid());
printf("PID:%d,leave\n",getpid());
sem_v(semid);
}
}