• 共享内存,消息队列


      一:共享内存

        共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是 Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递消息。

                      

        函数原型为:

        #include<sys/shm.h>

        1、int shmget(key_t key,size_t size,int shmflg);

        作用:新建一块内存或者返回已建好的内存

        参数:key,用于表示开辟一段内存,各进程通过这个标志访问同一块内存 size,内存的大小    shmflg,和文件操作完全相同权限表示,按位或IPC_CREATE表示创建一块内存,如果key表示的内存已经建立,即使加了 IPC_CREATE也不会新建一块内存,会返回key关联的内存。

      返回值:返回一个标示符,其他对共享内存的操作,用到该返回值

      2、void *shmat(int shm_id,const void * shm_addr,int shmflg);

      作用:讲一段共享内存连接到当前进程

      参数:shm_id,shmget的返回值

          shm_addr连接到当前进程的地址位置,一般为NULL,表示让系统来选择

          shmfig:SHM_RND,与shm_addr联合使用,控制连接地址

          SHM_RDONLY,只读   一般设为0

      返回值:指向共享内存第一字节的指针

      3、int shmdt(const void * shm_addr);

      作用:将共享内存从当前进程分离出去

      参数:shmat的返回值

      4、int shmctl(int shm_id,int command,struct shmid_ds * buf);

      structshmid_ds {

          uid_t shm_perm.uid;  

          uid_t shm_perm.gid;

          mode_t shm_prem.mode;

      }

      作用:对共享内存的控制

      参数:shm_id,shm_get的返回值

          commond,IPC_STAT:把shmid_ds中的值设为当前共享内存状态值

            IPC_SET:把共享内存状态设为shmid_ds中的值

             IPC_RMID:删除共享内存段

       下面是内存共享实现代码:

        申请一块共享内存,往内存里面写数据

     1 #include <stdio.h>
     2 #include <sys/ipc.h>
     3 #include <sys/shm.h>
     4 #include <unistd.h>
     5 #include <string.h>
     6 #include <stdlib.h>
     7 
     8 int main()
     9 {
    10     int ret = 0;
    11     //得到共享内存标识
    12     ret = shmget(IPC_PRIVATE, 1, IPC_CREAT);
    13     if(ret < 0) {
    14         perror("shmget");
    15         exit(EXIT_FAILURE);
    16     }
    17     printf("ret is %d
    ", ret);
    18 
    19     //获取共享内存地址(挂载)
    20     char *addr = (char *)shmat(ret, NULL, 0);
    21     if(addr == (void *) -1) {
    22         perror("shmat");
    23         exit(EXIT_FAILURE);
    24     }
    25     printf("addr is %p
    ", addr);
    26 
    27     char *buf = "hello world bunfly
    ";
    28     //向共享内存写数据
    29     strcpy(addr, buf);
    30     
    31     //解除关联(卸载)
    32     shmdt(addr);
    33         
    34     
    35 }

         读内存里面的数据:

          

     1 #include <stdio.h>
     2 #include <sys/ipc.h>
     3 #include <sys/shm.h>
     4 #include <unistd.h>
     5 #include <string.h>
     6 #include <stdlib.h>
     7 
     8 int main()
     9 {
    10     int ret = 950293;
    11     char buf[1024] = {0};
    12 
    13     //获取共享内存地址 (挂载)
    14     char *addr = (char *)shmat(ret, NULL, 0);
    15     if(addr == (void *) -1) {
    16         perror("shmat");
    17         exit(EXIT_FAILURE);
    18     }
    19     printf("addr is %p
    ", addr);
    20 
    21     //从共享内存读数据
    22     strcpy(buf, addr);
    23     printf("buf is %s
    ", buf);
    24     
    25     shmdt(addr);
    26 
    27     //删除共享内存地址
    28     if(shmctl(ret ,IPC_RMID,0)==-1) {
    29         perror("shmctl");
    30         exit(EXIT_FAILURE);
    31     }
    32 
    33     exit(EXIT_SUCCESS);    
    34 }

      二:消息队列    

      1:int msgget(key_t key, int msgflg);

      作用:创建和访问一个消息队列  

      参数:key,键值表示一个消息队列

     

             msgflg,权限标志位,与shmget标志位类似

     

      返回值:返回一个描述符,用于其他消息队列函数中

     

      2:int msgsnd(int msqid,const void * msg_ptr,size_t msg_sz,int msgflg);

     

         一般把消息用下边结构体表示

     

        struct my_message{

     

          long int message_type;//表示数据类型

     

          /*The data you wish to transfer*/

     

      }

     

         作用:把消息添加到消息队列

     

         参数:msqid,msgget的返回值

     

             msg_ptr,指向准备发送消息的指针

     

             msg_sz,消息长度不包括长整形消息类型变量

     

             msgflg控制当前队列满或达到系统最大限度时发生的事情,一般设为0

     

      3、int msgrcv(int msqid,void * msg_ptr,size_t msg_sz,long intmsgtype,int msgflg);

     

          作用:从消息队列中接收消息

     

          参数:msqid,msgget函数的返回值

     

              msg_ptr,指向准备接收消息的指针

     

              msg_sz,接受消息的大小,不包括表示类型的第一个变量

     

              msgtype,接受类型

     

              msgflg,控制没有消息接收时发生的事情,一般设为0

     

      5、int msgctl(int msqid,int commond,struct msqid_ds * buf);

     

      structmsqid_ds {

     

         uid_t msg_perm.uid;

     

         uid_t msg_perm.gid;

     

         mode_t msg_perm.mode;

      }

      消息队列实现代码:

      

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <sys/ipc.h>
     4 #include <sys/msg.h>
     5 int main()
     6 {
     7     //获得一个消息
     8     int ret = 0;
     9     ret = msgget(IPC_PRIVATE, IPC_CREAT);
    10     if(ret < 0) {
    11         perror("msgget");
    12         exit(EXIT_FAILURE);
    13     }
    14     
    15     return 0;
    16 }
     1 #include <stdio.h>
     2 #include <sys/ipc.h>
     3 #include <sys/msg.h>
     4 #include <string.h>
     5 #include <stdlib.h>
     6 
     7 struct msgbuf {
     8     int type; //数据类型
     9     char data[1024];
    10 };
    11 
    12 int main()
    13 {
    14     struct msgbuf info;
    15     info.type = 1;
    16     strcpy(info.data, "hello world");
    17     int id = 32769;
    18 
    19     //添加消息到消息队列
    20     int ret = msgsnd(id, &info, sizeof(struct msgbuf), 1);
    21     if(ret < 0) {
    22         perror("msgsnd");
    23         exit(EXIT_FAILURE);
    24     }
    25     
    26     return 0;        
    27 }

        从消息队列接收消息

     1 #include <stdio.h>
     2 #include <sys/ipc.h>
     3 #include <sys/msg.h>
     4 #include <stdlib.h>
     5  
     6 int main()
     7 {
     8     //msgget()函数返回的key值
     9     int id = 32769;
    10     int ret = 0;
    11     char data[1024] = {0};
    12 
    13     //接收消息
    14     ret = msgrcv(id, data, 1028, 1, 1); 
    15     if(ret < 0) {
    16         perror("msgrv");
    17         exit(EXIT_FAILURE);
    18     }    
    19     
    20     printf("%s
    ", data + 4);
    21 
    22     return 0;
    23 }
  • 相关阅读:
    通过scp拷贝文件时无需交互输入密码
    suse linux安装lrzsz
    shc加密shell脚本
    linux小程序--cmatrix
    linux系统PXE+Kickstart自动安装系统
    升级SSH
    shell生成随机数的几种方法
    django —— MVT模型
    Django学习---笔记一
    python学习--Django虚拟环境搭建
  • 原文地址:https://www.cnblogs.com/wenqiang/p/4747718.html
Copyright © 2020-2023  润新知