key_t键和ftok函数
系统建立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
以下为测试程序:
            #include <stdio.h>
            #include <sys/types.h>
            #include <sys/ipc.h>
#define IPCKEY 0x11
            int main( void )
            {
                 int i=0;
                 for ( i = 1; i < 256; ++ i )
                     printf( "key = %x\n", ftok( "/tmp", i ) );
return 0;
            }
在成功获取到key之后,就可以使用该key作为某种方法的进程间通信的key值,例如shmget共享内存的方式。
shmget的函数原型为
int shmget( key_t, size_t, flag);
在创建成功后,就返回共享内存的描述符。在shmget中使用到的key_t就是通过ftok的方式生成的
实例:
#include <sys/shm.h>
            #include <stdio.h>
            #include <errno.h>
            #include <string.h>
            #include <stdlib.h>
#define SIZE 1024
extern int errno;
int main()
            {
            int shmid;
            char *shmptr;
//创建共享内存
            if((shmid = shmget(IPC_PRIVATE, SIZE, 0600)) < 0)
                {
                 printf("shmget error:%s\n", strerror(errno));
                 return -1;
                }
//将共享内存连接到 可用地址上
if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1)
            {
                 printf("shmat error:%s\n", strerror(errno));
                 return -1;
            }
            memcpy(shmptr, "hello world", sizeof("hello world"));
            printf("share memory from %lx to %lx, content:%s\n",(unsigned long)shmptr, (unsigned long)(shmptr + SIZE), shmptr);
//拆卸共享内存
            if((shmctl(shmid, IPC_RMID, 0) < 0))
            {
                 printf("shmctl error:%s\n", strerror(errno));
                 return -1;
            }
            }
多进程之间共享内存情况:
#include <sys/shm.h>
            #include <stdio.h>
            #include <errno.h>
            #include <string.h>
            #include <stdlib.h>
            #include <unistd.h>
            #include <sys/types.h>
            #include <sys/wait.h>
#define SIZE 1024
extern int errno;
int main()
            {
            int shmid;
            char *shmptr;
            key_t key;
            pid_t pid;
if((pid = fork()) < 0)
            {
                 printf("fork error:%s\n", strerror(errno));
                 return -1;
                }
            else if(pid == 0)
                {
                  sleep(2);
                 if((key = ftok("/dev/null", 1)) < 0)
                 {
                   printf("ftok error:%s\n", strerror(errno));
                   return -1;
                 }
            if((shmid = shmget(key, SIZE, 0600)) < 0)
            {
                 printf("shmget error:%s\n", strerror(errno));
                 exit(-1);
                }
if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1)
            {
                 printf("shmat error:%s\n", strerror(errno));
                 exit(-1);
            }
            //memcpy(shmptr, "hello world", sizeof("hello world")); 
            printf("child:pid is %d,share memory from %lx to %lx,
content:%s\n",getpid(), (unsigned long)shmptr, (unsigned long)(shmptr +
SIZE
            ), shmptr);
            printf("child process sleep 2 seconds\n");
            sleep(2);
            if((shmctl(shmid, IPC_RMID, 0) < 0))
            {
                 printf("shmctl error:%s\n", strerror(errno));
                 exit(-1);
            }
                exit(0);
                }
                //parent
                else
                {
                 if((key = ftok("/dev/null", 1)) < 0)
                 {
                   printf("ftok error:%s\n", strerror(errno));
                   return -1;
                 }
            if((shmid = shmget(key, SIZE, 0600|IPC_CREAT|IPC_EXCL)) < 0)
{
                 printf("shmget error:%s\n", strerror(errno));
                 exit(-1);
                }
if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1)
            {
                 printf("shmat error:%s\n", strerror(errno));
                 exit(-1);
            }
            memcpy(shmptr, "hello world", sizeof("hello world"));
            printf("parent:pid is %d,share memory from %lx to %lx,
content:%s\n",getpid(),(unsigned long)shmptr, (unsigned long)(shmptr +
SIZE
            ), shmptr);
            printf("parent process sleep 2 seconds\n");
            sleep(2);
            if((shmctl(shmid, IPC_RMID, 0) < 0))
            {
                 printf("shmctl error:%s\n", strerror(errno));
                 exit(-1);
            }
                }
waitpid(pid,NULL,0);
            exit(0);
            }
输出为:

shmctl(shmid, IPC_RMID, 0)的作用是从系统中删除该恭喜存储段。因为每个共享存储段有一个连接计数(shmid_ds结构中的shm_nattch),所以除非使用该段的最后一个进程终止与该段脱接,否则不会实际上删除该存储段
key_t键和ftok函数的更多相关文章
- 【IPC通信】key_t键和ftok函数
		
System V IPC分为三种: System V消息队列 System V信号量 System V共享内存区 这三种类型的IPC使用key_t值做为它们的名字. key_t这个数据类型在<s ...
 - ftok()函数深度解析
		
[转载] 原文链接:https://blog.csdn.net/u013485792/article/details/50764224 关于ftok函数,先不去了解它的作用来先说说为什么要用它,共享内 ...
 - ftok函数
		
ftok函数 系统建立IPC通讯(消息队列.信号量和共享内存)时必须指定一个ID值.通常情况下,该id值通过ftok函数得到. ftok原型 头文件: #include <sys/types.h ...
 - ftok函数的使用
		
ftok函数的定义:系统建立IPC通讯 (消息队列.信号量和共享内存) 时必须指定一个ID值.通常情况下,该id值通过ftok函数得到. 头文件 #include <sys/types.h> ...
 - ftok函数例子
		
#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>int main( void ){ int ...
 - enter键触发的函数
		
enter键触发的函数示例: <input type="text" onkeydown="fun();"> function fun() { if( ...
 - php课程 4-17  数组键值操作函数有哪些
		
php课程 4-17 数组键值操作函数有哪些 一.总结 一句话总结:多看学习视频 1.php中数组的键值操作函数有哪6个? • array_values();获取数组中的值• array_keys( ...
 - mysql中,通过json_insert函数向json字段插入键值?json_insert函数的使用?
		
需求描述: 通过json_insert向json字段中插入值,在此进行实验,记录下. 操作过程: 1.查看已经有的包含json数据类型的表 mysql> select * from tab_js ...
 - jQuery元素属性attr设置多个键值或函数 删除属性removeAttr
		
$("Element").attr(name) '取得第一个匹配的属性值,比如$("img").attr("src") $("El ...
 
随机推荐
- windows azure programing
			
http://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-get-started-vs2012/ http:// ...
 - 数据库应该使用异步吗 Should my database calls be Asynchronous?
			
Should my database calls be Asynchronous? http://blogs.msdn.com/b/rickandy/archive/2009/11/14/should ...
 - asp.net中对象的序列化,方便网络传输
			
对象序列化 是将对象状态转换为可保持或传输的格式的过程.反序列化 是将流转换为对象序列化和反序列化相结合 可以使对象数据轻松的存储和传递 在 .NET 中,如果是对象可序列化,需要在 声明对象的开始部 ...
 - [转载]C#.NET中Dns类的常用方法及说明
			
IP是一种普遍应用于因特网.允许不同主机能够相互找到对方的寻址协议.IP地址由4个十进制的数字号码所组成,而每一个号码的值介于0~255之间,它虽然解决了网络上计算机的识别问题,但是IP地址确不容易记 ...
 - System.out.println(对象)
			
class Person { private String name; private int age; public String getName() { return this.name; } p ...
 - Java 8 vs. Scala(二):Stream vs. Collection
			
[编者按]在之前文章中,我们介绍了 Java 8和Scala的Lambda表达式对比.在本文,将进行 Hussachai Puripunpinyo Java 和 Scala 对比三部曲的第二部分,主要 ...
 - 九度 链表中倒数第k个结点
			
/* * a.cpp * * Created on: 2013-10-7 * Author: wangzhu */ #include<cstdio> #include<iostrea ...
 - apache的 .htaccess文件的常用配置
			
使用.htaccess文件需要注意的地方: 1.找到配置文件httpd.conf,将override的值改成all.如下图:(如果不设置成all,apache将忽略.htaccess文件)
 - Dagger 2: Step To Step
			
文/iamwent(简书作者)原文链接:http://www.jianshu.com/p/7505d92d7748著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 假设你已经了解 依赖注 ...
 - [置顶] *p++/*++p区别-linux
			
#include <stdio.h> main() { char * s = "123456"; char * p; p = s; printf( "%c\n ...