共享内存的概念
一个进程不能简单地将自己的内存空间地址传递给其他进程使用,这是因为Linux操作系统的内存保护机制或者说内存映射机制的限制。
在一个进程内,指向一块内存的指针实际上是虚拟地址,而不是真正的物理内存地址,这个地址仅在当前进程内使用才是有效的。
但是,如果通过某种方式能够实现多个进程访问一块物理内存,那么进程之间的数据交换就可以通过读写内存来进行,这将是一种效率很高的通信方式。
共享内存为在多个进程之间共享和传递数据提供了一种有效的方式。由于它并未提供同步机制,所以通常需要用其他的机制来同步对共享内存的访问。对共享内存的同步控制必须由程序员来负责。
共享内存的示意图:
API
系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。
ftok原型如下:
key_t ftok( char * fname, int id )
fname就时你指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255)。
当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回。
在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。如指定文件的索引节点号为65538,换算成16进制为 0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。 查询文件索引节点号的方法是: ls -i。
在成功获取到key之后,就可以使用该key作为某种方法的进程间通信的key值,例如shmget共享内存的方式。
//测试:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
int main( void )
{
int i=0;
for ( i = 1; i < 256; ++ i )
printf( "key = %x\n", ftok( "/tmp", i ) );
return 0;
}