共享内存(Shared Memory)是最简单的进程间通信方式,它允许多个进程访问相同的内存,一个进程改变其中的数据后,其他的进程都可以看到数据的变化。
共享内存是进程间最快速的通信方式:
`进程共享同一块内存空间。
`访问共享内存和访问私有内存一样快。
`不需要系统调用和内核入口。
`不造成不必要的内存复制。
内核不对共享内存的访问进行同步,因此程序员必须自己提供同步。
使用共享内存:
`某个进程分配内存段。
`使用这个内存段的进程要连接(attach)这个内存段。
`每个进程使用完共享内存段后,要分离(detach)这个内存段。
`在某个地方,必须有一个进程来销毁这个内存段。
Linux的内存模型:
`每个进程的虚拟内存被分为页(page)。
`每个进程维护自己的内存地址到虚拟内存页之间的映射。
`实际的数据存在于进程的内存地址上。
`尽管每个进程有自己的地址空间,多个进程的映射还是可以指向相同的页。
所有的共享内存段的大小,都是Linux内存页大小的整数倍。
Linux的页大小是4KB,不过程序员应该使用getpagesize函数来获得这个值。
分配:shmget
`第一个参数是一个整型的键,用于指定要创建的段。无关的进程可以通过指定同一个键来访问同一段共享内存。
`使用常量IPC_PRIVATE作为第一个参数,可以避免键的冲突。
`第二个参数是分配的段的大小(字节数)。实际分配的字节数会舍弃多余部分到页大小的整数倍。
`第三个参数是位标志,用来表示创建的选项。
``IPC_CREATE:表明要创建新的共享内存空间。
``IPC_EXCL:总是和上一个标志一起使用。如果指定键的共享内存段已经存在,这个标志会导致调用失败;如果没有指定这个标志,调用会返回已经占用这个键的共享内存段。
``模式标志:9个bit的标志,和系统的文件权限使用相同的标志,不过执行标志无效。这些标志定义在<sys/stat.h>中。
`返回值是新创建的或者取得的内存段的标志符(SHMID)。
连接:shmat
`第一个参数是由shmget得到的标志符(SHMID)。
`第二个参数是指向你想要映射到的本进程的地址空间的指针。如果指定NULL,Linux负责选择一个可用的地址。
/*共享内存 打印各种不同类型的数据所存放的位置 */
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 4000
#define MALLOC_SIZE 10000
#define SHM_SIZE 10000
#define SHM_MODE 0666 //设置读写权限
char array[ARRAY_SIZE];
main()
{
int shmid;
char *p,*shmp;
printf("array[] from %lx to %ls \n",(unsigned long)&array[0],(unsigned long)&array[ARRAY_SIZE] );
printf("stack around %lx \n",(unsigned long)&shmid);
if ((p = malloc(MALLOC_SIZE)) == NULL)
printf("malloc error! errno=%d\n",errno);
printf("malloced from %lx to %lx\n",(unsigned long)p,(unsigned long)p+MALLOC_SIZE);
if((shmid= shmget(IPC_PRIVATE,SHM_SIZE,SHM_MODE)) < 0){
if((shmid = shmget(IPC_PRIVATE,SHM_SIZE,IPC_CREAT|SHM_MODE)) < 0)
printf("creat shmget error! error=%d\n",errno);
exit(-1);
}
/*if((shmid = shmget(IPC_PRIVATE,SHM_SIZE,IPC_CREAT|SHM_MODE)) < 0)
printf("shmget error! errno=%d \n",errno);*/
if((shmp = shmat(shmid,0,0)) == (void*) -1)
printf("shmat error! errno=%d\n",errno);
printf("shared memory attached from %lx to %lx\n",(unsigned long)shmp,(unsigned long)shmp+SHM_SIZE);
if(shmctl(shmid,IPC_RMID,0) < 0)
printf("shmctl error! errno=%d\n",errno);
shmdt(shmp);
exit(0);
}
分享到:
相关推荐
在C语言中,`shmget()`获取或创建共享内存,`shmat()`附加到共享内存,`shmdt()`解除关联,`shmctl()`进行控制操作。`mutex`和`semaphore`常用于解决并发访问共享内存时的同步问题。 六、信号量(Semaphores) 信号...
5. **进程和线程**:理解进程的生命周期、进程间通信(IPC)方法,如管道、信号量、消息队列、共享内存,以及线程的创建和同步,如`pthread_create()`、`pthread_join()`、`mutex`和`condition_variable`。...
### Linux操作系统下C语言编程入门知识点 #### 一、基础知识 - **源程序编译**:在Linux环境下,使用GNU的`gcc`编译器来编译C语言源程序是最常见的做法。例如,对于一个简单的C语言源文件`hello.c`,可以通过命令`...
首先,Linux下的C语言编程基础涉及到标准输入输出、内存管理和文件I/O等基本概念。C语言在Linux中通过标准库提供接口,如`stdio.h`用于处理输入输出,`stdlib.h`用于内存分配和管理,以及`fcntl.h`用于文件操作。...
- **进程间通信(IPC)**: 包括管道(pipe)、命名管道(fifo)、信号量(semaphore)、共享内存(shared memory)等机制。 #### 第三章 文件操作 - **文件打开与关闭**: 如何使用`open()`和`close()`函数来打开和关闭文件...
进程间通信(IPC)是多进程协作的关键,包括管道、共享内存、消息队列、信号量等机制。线程则在单个进程中提供了并行执行的能力,线程的高级特性如线程同步(互斥锁、信号量)和线程池是提高程序性能的重要手段。 ...
在Linux环境下进行C语言编程,不仅需要掌握C语言的基础语法,还需要熟悉Linux系统的基本操作以及相关的开发工具。这个“Linux环境下C语言编程指南(源代码)”可能包含了从编写、编译、调试到优化C程序的全过程,...
本文将详细介绍Linux环境下C语言编程中的几种进程通信方法,包括POSIX无名信号量、System V信号量、System V消息队列以及System V共享内存。 #### 1. POSIX无名信号量 ##### 理论基础 信号量是一种用于控制多个...
在实际编程中,我们还需要了解如何有效地管理和使用进程间的通信(IPC)机制,如管道、套接字、共享内存等。这些工具允许进程之间交换数据,协同工作。虽然这些不在本节的直接讨论范围内,但它们与进程管理和信号...
在“Linux嵌入式C语言编程”这一主题中,我们主要探讨的是如何在Linux操作系统下进行C语言的编程工作,特别是在嵌入式系统中的应用。Linux作为一种开源且强大的操作系统,被广泛应用于各种设备,包括从微型嵌入式...
这组资源,"Linux下C语言应用编程(作者-杨铸)配套教学ppt",提供了对Linux环境下C语言编程的深入理解和实践指导。以下是一些核心知识点的详细说明: 1. **Linux下C语言编程环境**: - `11-Linux下C语言编程环境....
在Linux操作系统下学习C语言编程是一项基础且重要的技能,它涉及到多方面的知识。本文将针对提供的目录和部分内容,深入解析Linux环境下C语言编程的核心概念。 首先,了解**基础知识**是必要的,这包括对Linux环境...
UNIX系统支持多种进程间通信(IPC)机制,包括管道(pipe)、有名管道(fifo)、信号量(semaphore)、消息队列(message queue)、共享内存(shared memory)和套接字(socket)。这些机制在多进程程序中用于数据...
最后,进程间通信(IPC)在NIX平台上的C语言编程中占据重要地位,包括管道(pipe)、消息队列、共享内存、信号量和套接字等。这些机制允许不同进程之间交换数据,实现协同工作。 综上所述,NIX平台下的C语言高级...
理解进程间通信(IPC)机制,如管道、信号量、消息队列和共享内存,有助于实现复杂的并发程序设计。 3. **信号(Signals)**:Unix中的信号机制允许进程间进行异步通信。学习如何使用`signal()`, `sigaction()`等...
- 进程间通信(IPC)包括管道、信号量、共享内存等方式。 #### 三、文件操作 - 文件操作是C语言程序中的常见任务。 - Linux下的文件操作主要涉及文件的打开、读写、关闭等。 - 常用的文件操作函数包括`open()`、`...
理解进程间通信(IPC)如管道、信号量、共享内存等也是关键。 6. **网络编程**:UNIX系统下的网络编程主要基于Berkeley套接字(socket),涉及`<sys/socket.h>`和`<netinet/in.h>`等头文件,包括TCP/IP协议、UDP...