嵌入式 Linux进程间通信(八)——共享内存

嵌入式 Linux进程间通信(八)——共享内存

一、共享内存

共享内存允许两个或更多进程共享给定的内存区,数据不需要在不同进程间进行复制,是最快的进程间通信方式。使用共享内存唯一需要注意的是多个进程之间对给定存储区的同步访问,但共享内存本身没有提供同步机制,通常使用信号量来实现对共享内存访问的同步。

共享内存编程流程:创建共享内存、映射共享内存、使用共享内存、撤销映射操作、删除共享内存

1、创建共享内存

#include <sys/ipc.h>

#include <sys/shm.h>

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

key:非0整数

size:以字节为单位指定需要共享的内存容量

shmflg:权限标志,可以与IPC_CREAT做或操作

shmget函数成功时返回一个与key相关的共享内存标识符(非负整数)。调用失败返回-1.

2、映射共享内存

#include <sys/types.h>

#include <sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

shm_id是由shmget函数返回的共享内存标识。

shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。

shm_flg是一组标志位,通常为0。

调用成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1。

3、使用共享内存

可以使用不带缓存的IO函数对共享内存进行能操作

4、撤销映射共享内存操作

#include <sys/types.h>

#include <sys/shm.h>

int shmdt(const void *shmaddr);

将共享内存从当前进程中分离,shmaddr是shmat函数返回的地址指针,调用成功时返回0,失败时返回-1。

5、删除共享内存

#include <sys/ipc.h>

#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

shm_id是shmget函数返回的共享内存标识符。

command是要采取的操作,有三种操作:

IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。

IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值

IPC_RMID:删除共享内存段

buf是一个结构指针,它指向共享内存模式和访问权限的结构。

shmid_ds结构至少包括以下成员:

struct shmid_ds

{

uid_t shm_perm.uid;

uid_t shm_perm.gid;

mode_t shm_perm.mode;

};

二、共享内存编程实例

使用共享内存进行进程间通信程序实例:

shmdata.h文件(定义共享内存的数据结构):

#ifndef SHMDATA_H
#define SHMDATA_H
 
#define DATA_SIZE 1024
 
typedef struct shm
{
int flag;//非0,可读,0,可写
unsigned char data[DATA_SIZE];//数据
}share_memory;
#endif

shmread.c:

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>
#include <sys/shm.h>  
#include <sys/types.h>
#include <sys/ipc.h>
#include "shmdata.h"
 
int main(int argc, char **argv)
{
int shmid;
void *shm = NULL;
share_memory *shmdata;
key_t key = ftok("./shmread.c", ‘k‘);
shmid = shmget(key, sizeof(share_memory), 0666|IPC_CREAT);
if(shmid == -1)
{
fprintf(stderr, "shmget failed.\n");
exit(-1);
}
shm = shmat(shmid, 0, 0);
if(shm == (void *)-1)
{
fprintf(stderr, "shmat failed.\n");
exit(-1);
}
fprintf(stdout, "sharememory at 0x%X\n", shm);
shmdata = (share_memory *)shm;
shmdata->flag = 1;
int read = 1;
while(read)
{
if(shmdata->flag)
{
printf("share memory data:%s\n", shmdata->data);
shmdata->flag = 0;
}
else
{
printf("waiting...\n");
}
sleep(1);
}
if(shmdt(shm) == -1)
{
fprintf(stderr, "shmdt failed.\n");
exit(-1);
}
if(shmctl(shmid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "shmdt failed.\n");
exit(-1);
}
return 0;
}

shmwrite.c:

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <sys/shm.h>  
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include "shmdata.h"
 
int main(int argc, char **argv)
{
int shmid;
void *shm = NULL;
share_memory * shmdata;
key_t key = ftok("./shmread.c", ‘k‘);
shmid = shmget(key, sizeof(share_memory), 0666|IPC_CREAT);
char buffer[128] = "hello wolrd";
if(shmid == -1)
{
fprintf(stderr, "shmget failed.\n");
exit(-1);
}
shm = shmat(shmid, 0, 0);
if(shm == (void *)-1)
{
fprintf(stderr, "shmat failed.\n");
exit(-1);
}
fprintf(stdout, "sharememory at 0x%X\n", shm);
shmdata = (share_memory *)shm;
int read = 1;
while(read)
{
if(shmdata->flag == 0)
{
printf("writing...\n");
strncpy(shmdata->data, buffer,sizeof(buffer));
shmdata->flag = 1;
}
else
{
printf("waiting...\n");
}
sleep(1);
}
if(shmdt(shm) == -1)
{
fprintf(stderr, "shmdt failed.\n");
exit(-1);
}
return 0;
}
时间: 2024-08-05 03:09:11

嵌入式 Linux进程间通信(八)——共享内存的相关文章

Linux进程间通信—使用共享内存

Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像

Linux进程间通信——使用共享内存

下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样.而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程. 特别提醒:共

Linux进程间通信--mmap共享内存(一)

共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反之亦然.由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以. 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]:一次从输入

Linux进程间通信--shmget()共享内存(二)

共享内存区域是被多个进程共享的一部分物理内存.如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信.共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容.这块共享虚拟内存的页面,出现在每一个共享该页面的进程的页表中.但是它不需要在所有进程的虚拟内存中都有相同的虚拟地址. 图 共享内存映射图 象所有的 System V IPC对象一样,对于共享内存对象的获取

Linux进程间通信--mmap()共享内存(二)

内核怎样保证各个进程寻址到同一个共享内存区域的内存页面 1.page cache及swap cache中页面的区分:一个被访问文件的物理页面都驻留在page cache或swap cache中,一个页面的所有信息由struct page来描述.struct page中有一个域为指针mapping ,它指向一个struct address_space类型结构.page cache或swap cache中的所有页面就是根据address_space结构以及一个偏移量来区分的. 2.文件与addres

Linux进程间通信--shmget()共享内存(一)

大多数共享内存的具体实现,都是把由不同进程之间共享的内存映射为同一段物理内存. 多个进程都把该物理内存区域映射到自己的虚拟地址空间,这些进程就都可以直接访问该共享内存区域,从而可以通过该区域进行通信. 共享内存允许两个不相关的进程访问同一段物理内存, 由于数据不需要在不同的进程间复制,所以它是在两个正在运行的进程之间传递数据的一种非常有效的方式,一个进程向共享内存区域写入数据,共享该区域的所有进程就可以立刻看到其中的数据内容. 注意: 1.如上图所示,共享虚拟内存的页面,出现在每一个共享该页面的

Linux进程间通信——使用共享内存(转)

这篇文章将讲述别一种进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信--使用信号.下面就进入信号量的讲解. 一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更新的代码需要独占式地执行.而信号量就可以提供这样的一种访问机制,让一个临界区同

linux进程间通信之共享内存学习记录

进程 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed). 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动.它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元. 进程的概念主要有两点:第一,进程是一个实体.每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region).数据区域(data region)和堆

Linux进程间通信之共享内存

一,共享内存  内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存.  映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点: 优点:是最快的IPC. 缺点:要编程者自己实现对共享内存互斥访问.如何实现? 2,编程模型:具体函数的用法可以用man手册查看(强力推荐) 进程A: writeshm.c     1) 获得key, ftok()     2) 使用key来创建一个共享内存 shmget()      3) 映射