共享内存,消息队列

  一:共享内存

    共享内存指 (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\n", 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\n", addr);
26
27     char *buf = "hello world bunfly\n";
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\n", addr);
20
21     //从共享内存读数据
22     strcpy(buf, addr);
23     printf("buf is %s\n", 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\n", data + 4);
21
22     return 0;
23 }

        

时间: 2024-08-04 18:49:24

共享内存,消息队列的相关文章

第二十三天:共享内存.消息队列及mysql数据库使用

共享内存和消息队列也是进程间的通信方式. 共享内存,(和信号量的操作类似) #include<sys/shm.h> 1.int shmget(key_t key,size_t size,int shmflg); 作用:新建一块内存或者返回已建好的内存 参数:key,用于表示开辟一段内存,各进程通过这个标志访问同一块内存 size,内存的大小 shmflg,和文件操作完全相同权限表示,按位或IPC_CREATE表示创建一块内存,如果key表示的内存已经建立,即使加了IPC_CREATE也不会新建

进程间通信第二课--信号量 共享内存 消息队列

信号量 程序中存在一部分临界代码,要确保只有一个进程(或一个执行线程)可以进入临界区代码,并拥有对资源的独占式访问权 我们需要一种方法,通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域 这里讲的信号量比在线程的调用中使用的互斥量和信号量更加通用 P:等待,好像位于进入临界区域之前的检查点 V:给予或者释放,好像放弃对临界区域的控制权 P(sv):要是sv的值大于零,就减去1,如果它的值等于零,就挂起该进程的执行 V(sv):要是其他进程因等待sv而被挂起,就让它恢复运行,

云计算openstack共享组件-消息队列rabbitmq(2)

一.MQ 全称为 Message Queue, 消息队列( MQ ) 是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.   消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术.排队指的是应用程序通过队列来通信.队列的使用除去了接收和发送应用程序同时执行的要求.   排队指的是应用程序通过 队列来通信.队列的使用除去了接收和发送应用程序同时执行的要求.

node 内存消息队列

var net = require('net') var clients = [] ,msgs = {} function unWrapMsg(data){ data = data.toString().trim() var _d = data.split(':' , 2) _d[1] = _d[1] || '' var p1 = _d[0].trim() ,p2 = _d[1].trim() ,p3 = data.slice(_d[0].length + _d[1].length + 2) r

(总结)高并发消息队列常用通知机制

最近在研究一个高性能的无锁共享内存消息队列,使用的fifo来通知.结合之前<基于管道通知的百万并发长连接server模型>文章,这里总结一下常用的通知机制. 常用的通知机制中比较典型的有以下几种: 1.signal 这种机制下,我们向被通知进程发送一个特殊的signal(比如SIGUSR1),这样正在睡眠的读进程就会被信号中断,然后醒来. 该方法的优点是:读进程不需要监听一个额外的eventfd,适合一些不方便使用eventfd的场景:另外,用户可以选择是使用实时信号(SIGRTMIN+1),

项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享

因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXin(开源的微信开发SDK)开发的一款微信应用类系统,主要业务是围绕当下流行的微信元素,如:微官网.微商城.微分销.营销活动.会员卡等. 关于RabbitHub详情请戳: .NET 平台下的插件化开发内核(Rabbit Kernel) RabbitHub开源情况及计划 关于Rabbit.WeiXin详

MSMQ消息队列

一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能,并提供了与消息队列(MSMQ).COM+.Asp.net Web服务..NET Remoting等微软现有的分布式系统技术.利用WCF平台,开发人员可以很方便地构建面向服务的应用程序(SOA).可以认为,WCF是对之前现有的分布式技术(指的是MSMQ..NET Remoting和Web 服务等技术

跟我一起学WCF(1)——MSMQ消息队列

一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能,并提供了与消息队列(MSMQ).COM+.Asp.net Web服务..NET Remoting等微软现有的分布式系统技术.利用WCF平台,开发人员可以很方便地构建面向服务的应用程序(SOA).可以认为,WCF是对之前现有的分布式技术(指的是MSMQ..NET Remoting和Web 服务等技术

消息队列 链接

NAMEmq_overview —— POSIX消息队列概述 DESCRIPTIONPOSIX消息队列允许进程以消息的形式交换数据.此API与System V消息队列(msgget(2),msgsnd(2),msgrcv(2)等)有明显不同,但做的事情差不多. 消息队列通过mq_open(3)创建和打开,此函数返回一个消息队列描述符(mqd_t),它用于之后的调用中引用打开的消息队列.每个消息队列由一个名字标识,该名字具有这样的格式/somename,亦即,一个空字符结尾,以斜线开头,最多跟着N

进程间通信IPC:消息队列,信号量,共享内存

2015.3.4星期三 阴天 进程间通信:IPC 文件对象:记录文件描述符,文件开关等 IPC标示符:系统全局的流水号两个进程要通信,打开的是唯一的对象进行通讯,通过key操作 XSI IPC:消息队列,信号量,共享内存. ipcs 查看ip对象共享内存,信号量,消息队列等信息ipcrm 删除一个IP对象 Linux为用户提供了完善的,强大的网络功能完善的内置网络:其他操作系统不包含如此紧密的和内核结合在一起的网络部分 共享内存标示符的获取有两种方法:ftok(pathname,id)另一个是K