信号量控制三个进程打印ABC,共享内存,利用信号量实现共享内存的输入一次才能打印一次

一,利用信号量三个进程打印ABC

思想:
在这里插入图片描述

1,代码sem.h

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/sem.h>
#include<string.h>
#define SEMNUM 3
#define SEM1 0
#define SEM2 1
#define SEM3 2
union semun
{
int val;
}
int sem_init();
void sem_p(int index);
void sem_v(int index);
void sem_destroy();

2,代码sem.c

#include"sem.h"
int static semid=-1;
int sem_init()
{
semid=semget((key_t)1234,SEMNUM,IPC_CREAT|IPC_EXCL|0600)
if(semid==-1)
{
semid=semget((key_t)1234,SEMNUM,0600);
if(semid==-1)
{
printf("semget err\n");
return -1;
}
}
else
{
int b[SEMNUM]={1,0,0};
union semun a;
for(int i=0;i<SEMNUM;i++)
{
a.val=b[i];
if(semctl(semid,i,SETVAL,a)==-1)
{
printf("sem_init err\n");
return -1;
}
}
}
}
//注意这里只需要三个信号量中的一个来执行P操作;
void sem_p(int index)
{
if(index<0||index>=SEMNUM)
{
printf("index err\n");
return;
}
struct sembuf buf;
buf.sem_num=index;
buf.sem_op=-1;
buf.sem_flg=SEM_UNDO;
if(semop(semid,&buf,1)==-1)
{
printf("sem_p err\n");
return;
}
}

//如果需要三个信号量都执行P操作(这种情况很少见)
/*
void sem_p()
{
struct sembuf buf[SEMNUM];
for(int i=-0;i<SEMNUM;i++)
{
buf[i].sem_num=i;
buf[i].sem_op=-1;
buf[i].sem_flg==SEM_UNDO;
if(semop(semid,&buf[i],1)==-1)
{
printf("sem_p err\n");
return;
}
}
}

*/
void sem_v(int index)
{
printf("index err\n");
return;
}
struct sembuf buf;
buf.sem_num=index;
buf.sem_op=-1;
buf.sem_flg=SEM_UNDO;
if(semop(semid,&buf,1)==-1)
{
printf("sem_p err\n");
return;
}
}

void sem_destroy()
{
if(semctl(semid,0,IPC_RMID)==-1)
{
printf("sem_destroy erro\n");
return;
}
}

3,代码a.c

#include"sem.h"
int main()
{int flag=sem_init();
if(flag==--1)
{
printf("获取信号量失败\n");
}
for(int i=0;i<3;i++)
{
sem_p(SEM1);
printf("A");
fflush(stdout);
sem_v(SEM2);
}
}

4,代码b.c

#include"sem.h"
int main()
{int flag=sem_init();
if(flag==--1)
{
printf("获取信号量失败\n");
}
for(int i=0;i<3;i++)
{
sem_p(SEM2);
printf("B");
fflush(stdout);
sem_v(SEM3);
}
}

5,代码c.c

#include"sem.h"
int main()
{int flag=sem_init();
if(flag==--1)
{
printf("获取信号量失败\n");
}
for(int i=0;i<3;i++)
{
sem_p(SEM3);
printf("A");
fflush(stdout);
sem_v(SEM!);
}
}

二,共享内存

1,共享内存的原理(同时共享方式)

在这里插入图片描述
在这里插入图片描述

shmget函数
在这里插入图片描述
shmat函数
在这里插入图片描述

shmdt函数
如果一个进程结束了没有使用该函数断开映射也会自动断开映射;
在这里插入图片描述
shmctl函数
在这里插入图片描述

1.函数shma.c代码

刚开始的a.c代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<sys/shm.h>
#include<unistd.h>
#include<string.h>
int main()
{
int shmid=shmget((key_t)1234,128,IPC_CREAT|0600)
assert(shmid!=-1);
char*s=(char*)shmat(shmid,NULL,0);
//sleep(10);//这里是为了让我们看到共享内存的连接数不然程序一下结束就减一看不到连接数的变化;
strcpy(s,"hello");
shmdt(s);//注意如果这里没有断开映射,进程结束后会自动断开映射
}

在这里插入图片描述
在这里插入图片描述

2,函数shmb.c的代码

刚开始的shmb.c的代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<sys/shm.h>
#include<unistd.h>
#include<string.h>
int main()
{
int shmid=shmget((key_t)1234,128,IPC_CREAT|0600)
assert(shmid!=-1);
char*s=(char*)shmat(shmid,NULL,0);
printf("read: %s\n",s);
shmdt(s);
}

在这里插入图片描述

在这里插入图片描述

三,利用信号量实现共享内存的输入一次才能打印一次

在这里插入图片描述

1,改进后的shma.c的代码

1 #include<stdlib.h>
  2 #include<stdio.h>
  3 #include<assert.h>
  4 #include<unistd.h>
  5 #include<sys/shm.h>
  6 #include<string.h>
  7 #include"sema.h"
  8 int main()
  9 {
 10 int shmid=shmget((key_t)1234,128,IPC_CREAT|0600);
 11 assert(shmid!=-1);
 12 char*s=(char*)shmat(shmid,NULL,0);
 13 //sleep(10);
 14 sem_init();
 15 while(1)
 16 {
 17 printf("write: \n");
 18 char buff[128]={};
 19 fgets(buff,128,stdin);
 20 sem_p(SEM1);
 21 strcpy(s,buff);
 22 sem_v(SEM2);
 23 if(strncmp(buff,"end",3)==0)
 24 {
 25 break;
 26 }
 27 }
 28 shmdt(s);

2,改进后的代码shmb.c

1 #include<stdlib.h>
  2 #include<stdio.h>
  3 #include<assert.h>
  4 #include<unistd.h>
  5 #include<sys/shm.h>
  6 #include<string.h>
  7 #include"sema.h"
  8 int main()
  9 {
 10 int shmid=shmget((key_t)1234,128,IPC_CREAT|0600);
 11 assert(shmid!=-1);
 12 char*s=(char*)shmat(shmid,NULL,0);
 13 sem_init();
 14 while(1)
 15 {sem_p(SEM2);
 16  if(strncmp(s,"end",3)==0)
 17  {
 18  break;
 19  }
 20 printf("read: %s\n",s);
 21 sem_v(SEM1);
 22 //sleep(1);
 23 }
 24 shmdt(s);
 25 shmctl(shmid,IPC_RMID,NULL);
 26 sem_destroy();
 27 }

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值