信号量通信机制主要用来实现进程间同步,信号量用来标识系统可用资源的个数。
信号量管理操作
1. 创建信号量集合
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
2. 控制信号量集合、信号量
int semctl(int semid, int semnum, int cmd, ...);
3. 信号量操作
int semop(int semid, struct sembuf *sops, unsigned nsops);
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
static int semaphore_v(void);
static int set_semvalue(void);
static int get_semvalue(void);
union semun
{
int val;
struct semid_ds* buf;
unsigned short int* array;
struct seminfo* __buf;
};
int sem_id;
int main(int argc,char* argv[])
{
pid_t pid;
int i;
int value;
key_t key;
int status;
if((key = ftok(".",'B')) == -1)
perror("ftok ");
if((pid = fork()) == -1)
{
perror("fork ");
exit(-1);
}
else if(pid == 0)
{
if((sem_id = semget(key,1,IPC_CREAT|0777)) == -1)
perror("semget ");
if(!set_semvalue())
fprintf(stderr,"failed to initialize semphore\n");
value = get_semvalue();
printf("this is child,the current value is %d\n",value);
if(!semaphore_v())
fprintf(stderr,"failed to v operator\n");
value = get_semvalue();
printf("the child %d V operator,value %d \n",i,value);
printf("child exit sucess\n");
exit(0);
}
else{
sleep(3);
if((sem_id = semget(key,1,IPC_CREAT|0777)) == -1)
perror("semget ");
value = get_semvalue();
printf("this is parent,the current value is %d\n",value);
printf("the parent will remove the sem\n");
if(semctl(sem_id,0,IPC_RMID,(struct msquid_ds*)0) == -1)
perror("semctl");
return 0;
}
}
static int set_semvalue(void )
{
union semun sem_union;
int value;
sem_union.val = 5;
if(semctl(sem_id,0,SETVAL,sem_union) == -1)
return 0;
printf("set value success,");
printf("init value is %d\n",get_semvalue());
}
static int get_semvalue(void)
{
int res;
if((res = semctl(sem_id,0,GETVAL)) == -1)
perror("semctl");
return res;
}
static int semaphore_v(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
//sem_b.sem_op = 1; //V
sem_b.sem_op = -2; //P
//sem_b.sem_flg = 0;
sem_b.sem_flg = SEM_UNDO;
if(semop(sem_id,&sem_b,1) == -1)
perror("semop ");
return 1;
}
生产者与消费者问题
生产者代码
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<errno.h>
int sem_id;
void init()
{
key_t key;
int ret;
unsigned short sem_array[2];
union semun
{
int val;
struct semid_ds* buf;
unsigned short* array;
}arg;
key = ftok(".",'s');
sem_id = semget(key,2,IPC_CREAT|0644);
sem_array[0] = 0;
sem_array[1] = 100;
arg.array = sem_array;
ret = semctl(sem_id,0,SETALL,arg);
if(ret == -1)
perror("semctl ");
printf("productor init is %d\n",semctl(sem_id,0,GETVAL));
printf("space init is %d\n",semctl(sem_id,1,GETVAL));
}
void del()
{
semctl(sem_id,IPC_RMID,0);
}
int main(int argc,char* argv[])
{
struct sembuf sops[2];
sops[0].sem_num = 0;
sops[0].sem_op = 1;
sops[0].sem_flg = 0;
sops[1].sem_num = 1;
sops[1].sem_op = -1;
sops[1].sem_flg = 0;
init();
printf("this is productor\n");
while(1)
{
printf("\n\nbefore produce:\n");
printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
printf("space number is %d\n",semctl(sem_id,1,GETVAL));
semop(sem_id,(struct sembuf*)&sops[1],1);
printf("now producing ...\n");
semop(sem_id,(struct sembbuf*)&sops[0],1);
printf("\nafter produce\n");
printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
printf("space number is %d\n",semctl(sem_id,1,GETVAL));
sleep(4);
}
del();
}
消费者代码
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<errno.h>
int sem_id;
void init()
{
key_t key;
int ret;
unsigned short sem_array[2];
union semun
{
int val;
struct semid_ds* buf;
unsigned short* array;
}arg;
key = ftok(".",'s');
sem_id = semget(key,2,IPC_CREAT|0644);
}
int main(int argc,char* argv[])
{
init();
struct sembuf sops[2];
sops[0].sem_num = 0;
sops[0].sem_op = -1;
sops[0].sem_flg = 0;
sops[1].sem_num = 1;
sops[1].sem_op = 1;
sops[1].sem_flg = 0;
//init();
printf("this is customer\n");
while(1)
{
printf("\n\nbefore consume:\n");
printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
printf("space number is %d\n",semctl(sem_id,1,GETVAL));
semop(sem_id,(struct sembuf*)&sops[0],1);
printf("now consuming ...\n");
semop(sem_id,(struct sembbuf*)&sops[1],1);
printf("\nafter consume\n");
printf("productor number is %d\n",semctl(sem_id,0,GETVAL));
printf("space number is %d\n",semctl(sem_id,1,GETVAL));
sleep(3);
}
}