linux shmget ftok shmat shmdt shmctl函数

一 上一节的回顾

用 shmget 函数 创建了 共享内存 
用 icps -m xxx 删除了指定的内存 

二 上一节的补充

删除的是映射 为什么不是内核呢 
映射的过程

在这里插入图片描述

相当于 内核的东西换了一个位置 输出  方便用户使用 
节省了资源 删除也方便。

三 ftok shmget 函数配合生成的key值

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

name :文件名
int proj id :随机数字 (随意填1-65535
key 为 ftok 的返回值 
size :字节大小
shmflg:文件权限
#include<sys/shm.h>
#include<sys/types.h>
#include<stdio.h>
#include <sys/ipc.h>
#include<sys/msg.h>


 int main()
 {
     int res;
     int key;
     
     key=ftok("key.c",1);
     
     if(key<0)//出错 
     {
         printf("error");
         perror("why");
     }
     printf("ftok is sueecss ID is %d\n",key);
     res=shmget(key,128,IPC_CREAT|0777);
     
     if(res==-1)//出错 
     {
         printf("error\n");
         perror("***why:");
         return -2;
     }
     printf("shmget is sueecss ID is %d\n",res);
   
   return 0;
 }

在这里插入图片描述

生成的id 都是固定的 方便血缘关系的通信 (固定概念)

四 shmat 函数

在这里插入图片描述

这个函数用下面的 关系图 就可以解释和证明他的用处了

在这里插入图片描述

1 以前 我们在用户态写缓存 满足 条件之后 是往 内核里面的 但是现在不用了 
因为内核映射出了一个地址到了 用户态  
2 用户态的进程组 直接调用系统函数  对映射操作 
#include<sys/shm.h>
#include<sys/types.h>
#include<stdio.h>
#include <sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include <string.h>

 int main()
 {
     int res;
     int key;
      char *p=(char*)malloc(1024);
     key=ftok("key.c",1);
     if(key<0)
     {
         printf("error");
         perror("why");
     }
     printf("ftok is sueecss ID is %d\n",key);
     res=shmget(key,128,IPC_CREAT|0777);
     
     if(res==-1)
     {
         printf("error\n");
         perror("***why:");
         return -2;
     }
     printf("shmget is sueecss ID is %d\n",res);

     p = (char *)shmat(res,(void *)NULL,0);
     
     if(p==NULL)
     {
         printf("shamt is error\n");
         perror("why");
         return -5;
     }
       printf("sueecss\n");
       
      fgets(p,128,stdin);//输入
     
     printf("fgets is %s\n",p);//输出
       
      return 0;
 }

在这里插入图片描述

id :为shmget函数返回值
NULL:自动完成映射
0:可读写 

在这里插入图片描述

如果是在读一次呢 
#include<sys/shm.h>
#include<sys/types.h>
#include<stdio.h>
#include <sys/ipc.h>
#include<sys/msg.h>


 int main()
 {
     int res;
     int key;
      char *p;
     key=ftok("key.c",1);
     if(key<0)
     {
         printf("error");
         perror("why");
     }
     printf("ftok is sueecss ID is %d\n",key);
     res=shmget(key,128,IPC_CREAT|0777);
     
     if(res==-1)
     {
         printf("error\n");
         perror("***why:");
         return -2;
     }
     printf("shmget is sueecss ID is %d\n",res);

     p = (char *)shmat(res,(void *)NULL,0);
     
     if(p==NULL)
     {
         printf("shamt is error\n");
         perror("why");
         return -5;
     }
       printf("sueecss\n");
       
      fgets(p,128,stdin);//输入
     
     printf("one fgets is %s\n",p);//输出
     printf("two fgets is %s\n",p);//输出  
      return 0;
 }

在这里插入图片描述
能输出的原因

1 在创建的时候 会一直存在内核中 直到被删除或者系统关闭
2 共享内存和管道不一样 读取之后 内容不会消失 

共享内存映射到用户态的根据

假设1

1 写一个printf("hello\n"); : 写满缓存它会进入内核态 然后输出
看看结束的形式

在这里插入图片描述

换行就结束了 
共享内存的情况 (不进入内核态)

在这里插入图片描述

以空行结束

五 shmdt函数

在这里插入图片描述

函数指针可以存放指针
删除映射部分 

实验证明

删除映射部分 之后 在读取 如果 出现段错误 证明删除成功
#include<sys/shm.h>
#include<sys/types.h>
#include<stdio.h>
#include <sys/ipc.h>
#include<sys/msg.h>


 int main()
 {
     int res;
     int key;
      char *p;
     key=ftok("key.c",1);
     if(key<0)
     {
         printf("error");
         perror("why");
     }
     printf("ftok is sueecss ID is %d\n",key);
     res=shmget(key,128,IPC_CREAT|0777);
     
     if(res==-1)
     {
         printf("error\n");
         perror("***why:");
         return -2;
     }
     printf("shmget is sueecss ID is %d\n",res);

     p = (char *)shmat(res,(void *)NULL,0);
     
     if(p==NULL)
     {
         printf("shamt is error\n");
         perror("why");
         return -5;
     }
       printf("sueecss\n");
       
      fgets(p,128,stdin);//输入
     
     printf("one fgets is %s\n",p);//输出
     printf("two fgets is %s\n",p);//输出  
     
     shmdt((void*)p);//删除
     
   printf("fgets is %s\n",p);//输出    
      
      return 0;
 }

在这里插入图片描述

六 shmctl函数

在这里插入图片描述

主要看 第二个参数 
删除指令 IPC_RMID 调用函数可以有两种方法实现删除命令 加上 icprm -m xxx (无需调用函数的 )一共三种 

1 shmctl函数的使用第一种方法

在这里插入图片描述
参数配置

id:shmget返回值
command:IPC_RMID
buf :不指定 (NULL)
#include<sys/shm.h>
#include<sys/types.h>
#include<stdio.h>
#include <sys/ipc.h>
#include<sys/msg.h>
#include<string.h>

 int main()
 {
     int cv;
     int res;
     int key;
      char *p;
     key=ftok("key.c",1);
     if(key<0)
     {
         printf("error");
         perror("why");
     }
     printf("ftok is sueecss ID is %d\n",key);
     res=shmget(key,128,IPC_CREAT|0777);
     
     if(res==-1)
     {
         printf("error\n");
         perror("***why:");
         return -2;
     }
     printf("shmget is sueecss ID is %d\n",res);

     p = (char *)shmat(res,(void *)NULL,0);
     
     if(p==NULL)
     {
         printf("shamt is error\n");
         perror("why");
         return -5;
     }
       printf("sueecss\n");
       
      fgets(p,128,stdin);//输入
     
     printf("one fgets is %s\n",p);//输出
     printf("two fgets is %s\n",p);//输出  
     
     shmdt(p);//删除
     
  
    cv=shmctl(res,IPC_RMID,NULL);   
       if(cv==-1)
     {
         printf("error\n");
         perror("!!why:");
         return -2;
     }
       printf("shmctl is sueecss ID is %d\n"); 
      return 0;
 }

在这里插入图片描述

 生成了它,查看不到 所以 删除成功 

2 shmctl函数的使用第二种方法

使用main的形参实现

在这里插入图片描述

strmpy 字符串对比函数  
参数 :一样的类型 
0:就是相同
否则不同
#include<sys/shm.h>
#include<sys/types.h>
#include<stdio.h>
#include <sys/ipc.h>
#include<sys/msg.h>
#include <string.h>

 int main(int argc,char *argv[])
 
 {
     int shmid;
     int res;
      char *p;
     if(argc<2)
     {
         printf("argc is error");
         return -2;
     }
     
     if(strcmp(argv[1],"-m")==0)
     {
         printf("two can is sueecss\n");
     }
     shmid=ator(argv[2]);
     
     
     p= (char *)shmat(shmid,(void *)NULL,0);
     
      fgets(p,128,stdin);
     
     res=shmctl(shmid,IPC_RMID,NULL);
     
     if(res==-1)
     {
         printf("shmctl is error\n");
         perror("why");
         retun -100;
     }
     printf("shmctl is sueecss\n");
     
        
   return 0;
 }

在这里插入图片描述

./a.out :argv[0]
-m  : argv[1]
xxx:argv[2]

3 不使用shmctl函数第三种方法

方法 3 :ipcrm -m xxx

在这里插入图片描述

删除了 就不存在了 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值