共享内存,消息队列

  一:共享内存

    共享内存指 (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 }
原文地址:https://www.cnblogs.com/wenqiang/p/4747718.html