1,完成图片上的操作
代码:
#include <myhead.h>
#include "sem.h"
int main(int argc, const char *argv[])
{
//定义并初始化信号灯集
int semid=init_sem(4);
//定义key的值
key_t key;
if((key=ftok("/",'k'))==-1){
perror("ftok error");
return -1;
}
//定义一个共享内存
int shmid;
if((shmid=shmget(key,4096,IPC_CREAT|0664))==-1){
perror("shmget error");
return -1;
}
//映射虚拟内存
char *addr=NULL;
if((addr=shmat(shmid,NULL,0))==(void *)-1){
perror("shmat error");
return -1;
}
//定义进程
pid_t pid;
pid=fork();
if(pid<0){
perror("pid error");
return -1;
}else if(pid==0){
while(1){
//此进程的父子进程的切换
V(semid,0);
//等待3号灯的资源
P(semid,3);
printf("%s\n",addr);
//释放2号灯的资源
V(semid,2);
if(strcmp(addr,"quit")==0){
break;
}
}
}else
{
while(1){
//等待0号灯的资源
P(semid,0);
fgets(addr,4096,stdin);
addr[strlen(addr)-1]='\0';
//释放1号灯的资源
V(semid,1);
if(strcmp(addr,"quit")==0){
break;
}
}
}
//取消映射
if(shmdt(addr)==-1){
perror("shmdt error");
return -1;
}
//删除信号灯集
del_sem(semid);
//删除共享内存
if(shmctl(shmid,IPC_RMID,NULL)==-1){
perror("shmctl error");
return-1;
}
return 0;
}
#include <myhead.h>
#include "sem.h"
int main(int argc, const char *argv[])
{
//定义信号灯集并初始化
int semid=init_sem(4);
//定义key的值
key_t key;
if((key=ftok("/",'k'))==-1){
perror("ftok error");
return -1;
}
//定义一个共享内存
int shmid;
if((shmid=shmget(key,4096,IPC_CREAT|0664))==-1){
perror("shmget error");
return -1;
}
//映射虚拟内存
char *addr=NULL;
if((addr=shmat(shmid,NULL,0))==(void *)-1){
perror("shmat error");
return -1;
}
//定义进程
pid_t pid;
pid=fork();
if(pid<0){
perror("pid error");
return -1;
}else if(pid==0){
while(1)
{
//此进程的父子进程之间的切换
V(semid,2);
//等待1号灯的资源
P(semid,1);
printf("%s\n",addr);
//释放0号灯的资源
V(semid,0);
if(strcmp(addr,"quit")==0){
break;
}
}
}else
{
while(1){
//等待2号灯的资源
P(semid,2);
fgets(addr,4096,stdin);
addr[strlen(addr)-1]='\0';
//释放3号灯的资源
V(semid,3);
if(strcmp(addr,"quit")==0){
break;
}
}
}
//取消映射
if(shmdt(addr)==-1){
perror("shmdt error");
return -1;
}
return 0;
}
#include <myhead.h>
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
int sem_value(int semid,int semno,int semval){
union semun us;
us.val=semval;
if(semctl(semid,semno,SETVAL,us)==-1)
{
perror("semctl error");
return -1;
}
return 0;
}
//创建一个信号灯集并初始化
int init_sem(int semnum){
//创建key值
key_t key;
if((key=ftok("/",'k'))==-1){
perror("key error");
return -1;
}
//创建信号灯集
int semid;
if((semid=semget(key,semnum,IPC_CREAT|IPC_EXCL|0666))==-1){
if(errno == EEXIST){
semid=semget(key,semnum,IPC_CREAT);
return semid;
}else{
perror("semid error");
}
return -1;
}
//信号灯集初始化
for(int i=0;i<semnum;i++){
if(i==0){
sem_value(semid,i,1);
}else{
sem_value(semid,i,0);
}
}
return semid;
}
//声明一个p操作函数
int P(int semid,int semno){
struct sembuf buf;
buf.sem_num=semno;//要操作的信号灯编号
buf.sem_op=-1;//表示要进行申请资源
buf.sem_flg=0;//表示阻塞申请资源
if(semop(semid,&buf,1)==-1){
perror("semop error");
return -1;
}
return 0;
}
//声明一个V操作函数
int V(int semid,int semno){
struct sembuf buf;
buf.sem_num=semno;
buf.sem_op=1;
buf.sem_flg=0;
if(semop(semid,&buf,1)==-1){
perror("semop error");
return -1;
}
return 0;
}
//声明一个删除信号灯集
int del_sem(int semid){
if(semctl(semid,0,IPC_RMID,0)==-1){
perror("semctl error");
return -1;
}
return 0;
}
运行结果:
2,思维导图