对System V 信号量的使用

该文章主要是讲解了sem_p,sem_v的操作,对于多进程同时操作共享内存时,利用对semget,semctl实现对互斥量的同步。

#include <sys/shm.h>

#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#define SHMKEY 123456
#define SEMKEY 1234567
typedef struct SHMADDR{
int num;
}SHMADDR;
SHMADDR *addr;
int semid;
int shmid;
struct sembuf buf;
int sem_p(){
buf.sem_num=0;// 信号量的编号,p 和v 操作时是依赖这个参数来确定唤醒的是哪组信号量
buf.sem_op=-1;
buf.sem_flg=SEM_UNDO;//避免进程异常退出造成死锁。
semop(semid,&buf,1);
}
void sem_v()
{
buf.sem_num =0;
buf.sem_op =1;
buf.sem_flg =SEM_UNDO;
semop(semid,&buf,1);
}
void sig_handle(int arg)
{
printf("捕获到退出信号%d,pid=%d\n",arg,getpid());
shmctl(shmid,IPC_RMID,0);
semctl(semid,0,IPC_RMID);
exit(0);
}
void child_fork()// shared mem num+1;
{
while(1)
{
sem_p();// 进入临界区,信号量的值减一。则此时信号量的值为0.别的进程不在可以进入了。
addr->num +=1;
printf("child fork num is{%d}\n",addr->num);
sem_v();// 出来临界区,并且把信号量的值+1.又恢复成1.
sleep(1);
}
}
void parent_fork()// shared mem num -1;
{
while(1){
sem_p();
addr->num -=1;
printf("parent fork num is{%d}\n",addr->num);
sem_v();
sleep(1);
}
}
int main()
{
int pid;
shmid =shmget(SHMKEY,sizeof(SHMADDR),IPC_CREAT|IPC_EXCL|0666);
addr = shmat(shmid,NULL,0);
addr->num =10;// 共享内存里的num 设置为10.
semid =semget(SEMKEY,1,IPC_CREAT|0600);/ /第二个参数设置为1. 是说明只有1组信号量在操作。
semctl(semid,0,SETVAL,1);// 信号量的值为1.
signal(SIGTERM,sig_handle);
signal(SIGINT,sig_handle);
pid =fork();
if (pid <0)
{
perror("fork()");
}
else if (pid ==0)
{
child_fork();
}
else if (pid >0)
{
parent_fork();
}
while (1);
return 0;
}

猜你喜欢

转载自blog.csdn.net/linke_linux/article/details/79658375
今日推荐