在上一篇共享内存的基础上加上pv操作,也就是 A 进程去写 的时候要加上P 写完了 加个 V
pvwrite.cpp
#include "public.h"
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int main()
{
SNode student;
char buffer[20];
pid_t pid=0;
int i=1;
int ret=0;
//嵌入式信号量代码
union semun mysemun;
struct sembuf mysembuf;
int sem_no =0;
//创建信号
sem_no=semget(SEM_KEY,SEM_NUMBER,SEM_FLAG);
if (sem_no==-1)
{
printf("fail to semget SEM_KEY=%d \n",SEM_KEY);
exit(1);
}
//2.设置初值
mysemun.val=1;
ret=semctl(sem_no,SEM_INDEX,SETVAL,mysemun);
if (ret==-1)
{
printf("fail to call semctl \n");
}
//执行你的非关键代码
//创建信号
sem_no=semget(SEM_KEY,SEM_NUMBER,SEM_FLAG);
if (sem_no==-1)
{
printf("fail to semget SEM_KEY=%d \n",SEM_KEY);
exit(1);
}
//进行p操作准备执行关键代码
mysembuf.sem_num=SEM_INDEX;
mysembuf.sem_op=-1;
mysembuf.sem_flg=SEM_UNDO;
ret=semop(sem_no,&mysembuf,1);
if (ret==-1)
{
printf("fail to call semop p op\n");
}
//开辟一个可以存储10个学生信息的共享内存空间
mem_no=shmget(MEM_KEY,10*MEM_SIZE,MEM_FLAG);
if (mem_no==-1)
{
printf("fail to shmget\n");
exit(0);
}
//共享内存的周地址映射到本进程
pstudent=(StuNodes)shmat(mem_no,NULL,0);
//保留开始的位置方便后续读取
pstudent_first=pstudent;
pstudent_first2=pstudent;
//写入学生到共享内存中
for (i=0;i<10;i++)
{
student.no=i;
sprintf(buffer,"student %d",i);
strcpy(student.username,buffer);
memcpy(pstudent,&student,MEM_SIZE);
//移动共享内存到下一个位置进行写入
pstudent++;
printf("write %d student \n",i);
sleep(1);
}
//关键代码执行完了之后,做一个v操作让别的进程的p
//能够进去
mysembuf.sem_num=SEM_INDEX;
mysembuf.sem_op=1;
mysembuf.sem_flg=SEM_UNDO;
ret=semop(sem_no,&mysembuf,1);
if (ret==-1)
{
printf("fail to semop v op\n");
}
printf("press anykey to exit \n");
getchar();
//删除sem_no
semctl(sem_no,SEM_INDEX,IPC_RMID);
return 0;
}