键值 = 文件标示符 + 项目ID

当用到进程间的通信时, 必须要注意到的是键值是怎么产生的,我们知道任何一个文件时通过文件名来访问的, 而内核在对应的给其一个值,也就是文件标示符。

系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值 。通常情况下,该id值通过ftok函数得到 。  ftok原型如下:
key_t ftok( char * fname, int id )

此时这个 id也就是项目 ID,最后将两者结合生成了键值!这里所谓的文件标示符其实下面提到的 内核的物理编号,也就是索引节点 inode。

参数说明: fname就时您指定的文档名,  id是子序号。

关于linux中的软链接和硬链接

Linux中有两种类型的链接:(这个与 Windows上 FAT32 或 NTFS是不一样的!)

硬链接是利用Linux中为每个文件分配的物理编号——inode建立链接。因此,硬链接不能跨越文件系统。(用ls –i命令可以查看目录下文件的inode编程)。

软链接(符号链接)是利用文件的路径名建立链接。通常建立软链接使用绝对路径而不是相对路径,以最大限度增加可移植性。

i节点包含了所有与文件有关的信息:文件类型、文件存取许可权位、文件长度和指向该文件所占用的数据块的指针等,stat结构中的大多数信息都取自 i节点。只有两数据项存放在目录项中:文件名和i节点编号数。

因为目录项中的i节点编号数指向同一文件系统中的 i节点,所以不能使一个目录项指向另一个文件系统的i节点。硬链接不能跨文件系统,软链接可以。即每个文件系统有自己的i节点编号。

在一般的UNIX实现中,是将文档的索引节点号取出,前面加上子序号得到key_t的返回值。 如指定文档的索引节点号为65538,换算成16进制为0x010002,而您指定的ID值为38,换算成16进制   为 0x26,则最后的key_t返回值为0x26010002。
查询文档索引节点号的方法是: ls -i
当删除重建文档后,索引节点号由操作系统根据当时文档系统的使用情况分配,因此和原来不同,所以得到的索引节点号也不同。
    假如要确保key_t值不变,要目确保ftok的文档不被删除 ,要么不用ftok,指定一个固定的key_t值。
另外说一句:在aix等操作系统上,有多个文档系统,会出现分布在不同的文档系统上的两个文档具备相同的索引节点号,此时用ftok对这两个文档进行操作,只要id参数不变,得到的key_t值相同,造成创建消息队列失败。但是这种情况相当少见罢了。

因为在开发中涉及多种系统平台,在系统移植时发现ftok()函数在不同平台下存在一定的差异性。当然,根本原因不在于ftok()本身,而应该是操作系统对于文件系统管理的差异性。

测试代码如下:
[code]#include ;
#include ;

main()
{
    sprintf( "key=%0x/n", ftok( "aaa.txt", 1000 ) );
}
[/code]

测试涉及的操作系统:RedHat AS3U3、Sco OpenServer 5.0.6、UnixWare 7.1.1、Solaris 9 x86 u7。

在RH AS3环境下,对aaa.txt进行修改后程序的输出值都有变化,说明该文件在修改后存储位置发生了变化。

在Sco OpenServer 5.0.6、UnixWare 7.1.1、Solaris 9 x86 u7下执行相同的程序,无论对aaa.txt的文件内容做何种修改都对程序的输出无影响。

因此,如果在linux下通过ftok()产生ipc键值、且ftok()与配置文件相关,则在更改了配置文件后必须将应用重起。否则将导致不可预料的后果!

看以下程序:

  头文件:
 
  #include
 
  #include
 
  如下:
 
  key_t ftok( char * fname, int id )
 
  fname就是你指定的文件名(已经存在的文件名),一般使用当前目录,如:
 
  key = ftok(".", 1); 这样就是将fname设为当前目录。
 
  id是子序号。
 
  在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。
 
  如指定文件的索引节点号为65538,换算成16进制为0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。
 
  查询文件索引节点号的方法是: ls -i
 
  当删除重建文件后,索引节点号由操作系统根据当时文件系统的使用情况分配,因此与原来不同,所以得到的索引节点号也不同。
 
  如果要确保key_t值不变,要么确保ftok的文件不被删除,要么不用ftok,指定一个固定的key_t值,比如:
 
  #define IPCKEY 0x111
 
  char path[256];
 
  sprintf( path, "%s/etc/config.ini", (char*)getenv("HOME") );
 
  msgid=ftok( path, IPCKEY );
 
  同一段程序,用于保证两个不同用户下的两组相同程序获得互不干扰的IPC键值。
 
  由于etc/config.ini(假定)为应用系统的关键配置文件,因此不存在被轻易删除的问题——即使被删,也会很快被发现并重建(此时应用系统也将被重起)。  
 

深入解读键值产生原理,linux中的软链接和硬链接(转)的更多相关文章

  1. Linux中的软链接与硬链接

    软链接相当于windows的快捷方式,当源文件不存在时,软链接失效. 链接是指向文件名,当指向的文件名字删除的时候,就找不到源文件了.硬链接是指向文件本身,删除一个文件名字,还是可以找到源文件的.ls ...

  2. linux中的软、硬链接

    linux中的软.硬链接 硬链接 硬链接(hard link),如果文件B是文件A的硬链接,则A的inode节点号与B的inode节点号相同,即一个inode节点对应两个不同的文件名,两个文件名指向同 ...

  3. Linux学习笔记 软链接和硬链接

    Linux 中,"everything is file".接下来给大家介绍 linux 如何通过链接,达到节省磁盘空间.共享文件等目的.链接文件有两种方式,软链接(soft lin ...

  4. 2017-7-18-每日博客-关于Linux下的软链接和硬链接.doc

    ln命令 该命令在文件之间创建链接.这种操作实际上是给系统中已有的某个文件指定另外一个可用于访问它的名称.对于这个新的文件名,我们可以为之指定不同的访问权限,以控制对信息的共享和安全性的问题. 如果链 ...

  5. Linux文件的软链接和硬链接

    1.Linux链接概念 Linux链接分两种,一种被称为硬链接(Hard Link).还有一种被称为符号链接(Symbolic Link).默认情况下.ln命令产生硬链接. 1.1索引节点 索引节点是 ...

  6. Linux常用基本命令(软链接与硬链接 )

    硬链接:相当于文件的多个入口,作用:备份文件,创建快照等 软链接:相当于windows的快捷方式 命令格式: ln option 源文件 目标文件 -s: 创建软链接 1,创建硬链接: ghostwu ...

  7. linux下的软链接与硬链接

    在 Linux 底下的连结档有两种,一种是类似 Windows 的快捷方式功能的文件,可以让你快速的链接到目标文件(或目录);这种链接称为软链接. 另一种则是透过文件系统的 inode 连结来产生新档 ...

  8. linux 创建软链接和硬链接

    Linux 系统中有软链接和硬链接两种特殊的“文件”. 软链接可以看作是Windows中的快捷方式,可以让你快速链接到目标档案或目录. 硬链接则透过文件系统的inode来产生新档名,而不是产生新档案. ...

  9. linux中inode、软链接、硬链接

    1 软链接 linux中软链接理解成window中的快捷方式.创建软链接的命令 ln -s 源文文件或目录 目标文件或目录 2 硬链接 创建硬链接的命令如下 ln  源文文件或目录 目标文件或目录 3 ...

随机推荐

  1. 梯度消失(vanishing gradient)与梯度爆炸(exploding gradient)问题

    (1)梯度不稳定问题: 什么是梯度不稳定问题:深度神经网络中的梯度不稳定性,前面层中的梯度或会消失,或会爆炸. 原因:前面层上的梯度是来自于后面层上梯度的乘乘积.当存在过多的层次时,就出现了内在本质上 ...

  2. Linux上传和下载之Xshell

    一.安装与授权 安装时候需要注意的是,选择 Free For Home/School选项进行安装,如下图所示安装成功后 二.上传 上传需要使用rz命令,如下图所示,第一次可能会提示你命令无效或者提示你 ...

  3. Android 演示 Android ListView 和 github XListView(3-3)

    本文内容 环境 项目结构 演示 1:简单 XListView 演示 2:XListView + Fragment 演示 3:XListView + ViewPager + Fragment 本文三个演 ...

  4. Android LazyList 从网络获取图片并缓存

    原演示地址 本文内容 环境 演示 LazyList 从网络获取图片并缓存 参考资料 本文是 Github 上的一个演示,通过网络获取歌手专辑的缩略图,并显示在 ListView 控件中.该演示具备将缩 ...

  5. Fragment的setUserVisibleHint方法实现懒加载,但setUserVisibleHint 不起作用?

    我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在 ...

  6. Qt通过ODBC连接SQL Server2008实践总结

    Qt连接数据库的方式很多,这里说明一种最常用也是最实用的方式,因为这种方式在Windows上开发程序使用起来非常方便,并且也是远程连接数据库所需要用到的方式. 前提工作: 在Win7下安装了SQL S ...

  7. Android下雪动画的实现

    原文链接 : Snowfall 原文作者 : Styling Android 译文出自 : hanks.xyz 译者 : hanks-zyh 校对者: desmond1121 状态 : 完毕 这本是一 ...

  8. python获取系统开机时间

    import psutil import time time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(psutil.boot_time()))

  9. hibernate和struts实现分页

    仓促把功能进行实现一下  类与类之间也没有进行MVC式分开  重要的是逻辑 记录一下 希望其中的些许代码逻辑对你有用 TUserDaoImpl---dao层的实现 package com.pers.h ...

  10. cocos2d-js 自定义事件监听派发

    熟悉js的dom事件或者flash事件的,基本都能立马明白cc.eventManager的用法. cc.eventManager有两种注册监听器的方式,一种是原生事件,例如 cc.eventManag ...