首页 > 系统相关 >【linux基础】ftok函数解析

【linux基础】ftok函数解析

时间:2023-05-23 18:44:41浏览次数:45  
标签:unsigned long st 键值 key linux ftok 解析

前言

最新项目代码有关信号量、共享内存,直接使用数值,不能得到预想的效果,调试发现不能直接使用数值,而是ftok函数获取键值,此前不了解,故记录之。

原理

共享内存、消息队列、信号量都是通过一个中间介质来进行通信的,这种介质多的是。就是怎么区分出来,就像唯一一个身份证来区分人一样。你随便来一个就行,就是因为这。只要唯一就行,就想起来了文件的设备编号和节点,它是唯一的,但是直接用它来作识别好像不太好,不过可以用它来产生一个号。ftok()就出场了。

函数形式

 key_t ftok(const char *pathname, int proj_id);

函数常见问题

1.pathname是目录还是文件的具体路径,是否可以随便设置
答:ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置。
2.pathname指定的目录或文件的权限是否有要求
答:该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
3.proj_id是否可以随便设定,有什么限制条件

答:proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255。

函数使用陷阱

在使用ftok()函数时,里面有两个参数,即fname和id,fname为指定的文件名,而id为子序列号,这个函数的返回值就是key,它与指定的文件的索引节点号和子序列号id有关,这样就会给我们一个误解,即只要文件的路径,名称和子序列号不变,那么得到的key值永远就不会变。
事实上,这种认识是错误的,想想一下,假如存在这样一种情况:在访问同一共享内存的多个进程先后调用ftok()时间段中,如果fname指向的文件或者目录被删除而且又重新创建,那么文件系统会赋予这个同名文件新的i节点信息,于是这些进程调用的ftok()都能正常返回,但键值key却不一定相同了。由此可能造成的后果是,原本这些进程意图访问一个相同的共享内存对象,然而由于它们各自得到的键值不同,实际上进程指向的共享内存不再一致;如果这些共享内存都得到创建,则在整个应用运行的过程中表面上不会报出任何错误,然而通过一个共享内存对象进行数据传输的目 的将无法实现。
这是一个很重要的问题,希望能谨记!!!
所以要确保key值不变,要么确保ftok()的文件不被删除,要么不用ftok(),指定一个固定的key值。

ubuntu中ftok产生键值的原理

#include <stdio.h>       
#include <stdlib.h>  
#include <sys/stat.h>
 
int main()
{
        char    filename[50];
        struct stat     buf;
        int     ret;
        strcpy( filename, "/home/satellite/" );
        ret = stat( filename, &buf );
        if( ret )
        {
                printf( "stat error\n" );
                return -1;
        }
 
        printf( "the file info: ftok( filename, 0x27 ) = %x, st_ino = %x, st_dev= %x\n", ftok( filename, 0x27 ), buf.st_ino, buf.st_dev );
 
        return 0;
}

通过执行结果可看出,ftok获取的键值是由ftok()函数的第二个参数的后8个bit,st_dev的后两位,st_ino的后四位构成的

通过ftok返回的是根据文件(pathname)信息和计划编号(proj_id)合成的IPC key键值,从而避免用户使用key值的冲突。proj_id值的意义让一个文件也能生成多个IPC key键值。ftok利用同一文件最多可得到IPC key键值0xff(即256)个,因为ftok只取proj_id值二进制的后8位,即16进制的后两位与文件信息合成IPC key键值。

有关 st_dev和 st_ino的定义如下:

函数:int stat( const char *file_name, struct stat *buf )
函数说明:通过文件名filename,获取文件信息,并保存在buf所指的结构体stat中。
返回值:成功执行返回0,失败返回-1,错误代码存于errno
struct stat结构体的定义如下:
/usr/include/asm/stat.h
struct stat {
       unsigned long  st_dev;//文件的设备编号
       unsigned long  st_ino;//节点
       unsigned short st_mode; //文件的类型和存取的权限
       unsigned short st_nlink;//连到该文件的硬连接数目,刚建立的文件值为1
       unsigned short st_uid; //用户ID
       unsigned short st_gid; //组ID
       unsigned long st_rdev; 
       unsigned long  st_size;
       unsigned long st_blksize;
       unsigned long  st_blocks;
       unsigned long  st_atime;
       unsigned long st_atime_nsec;
       unsigned long  st_mtime;
       unsigned long st_mtime_nsec;
       unsigned long  st_ctime;
       unsigned long st_ctime_nsec;
       unsigned long  __unused4;
       unsigned long  __unused5;
};

项目问题

最早是直接设置数值作为键值,与当前项目的键值获取方式不一致,导致共享内存的数据有误。

#define Sem_Camera_Key 0x53  #注意0x是十六进制
#define Shm_Camera_Key 0x54
#define Shm_Camera_Data_Size   (640*480*3)

更改为

#ifndef KEY_PATH
#define KEY_PATH    "/home/root/hzp"
#endif

#define Sem_Camera_Key ftok(KEY_PATH, 53)
#define Shm_Camera_Key ftok(KEY_PATH, 54)
#define Shm_Camera_Data_Size   (640*480*3)

 

 

 

参考

1. ftok()函数深度解析_satellite13的博客-CSDN博客

2. linux进程间通信--消息队列相关函数(ftok)详解_andylauren的博客-CSDN博客

 

标签:unsigned,long,st,键值,key,linux,ftok,解析
From: https://www.cnblogs.com/happyamyhope/p/17425963.html

相关文章

  • RAW8图像数据格式解析
    前言使用7yuv工具查看raw8图像数据,选择的格式是8bpp格式,大小是图像尺寸1280*720即可;RAW格式raw数据是sensor输出的原始数据,一般有raw8,raw10,raw12等,分别表示一个像素点有8bit、10bit、12bit数据。是sensor将光信号转化为电信号时的电平高低的原始记录,单纯地没有进行任何处......
  • linux nfs共享存储服务
    目录一、nfs服务二、nfs优点三、配置文件四、共享文件配置过程五、实验1.创建共享文件(两台终端共享)              一、nfs服务概念:网络上共享文件系统的协议,运行多个服务器之间通过网络共享文件和目录服务端:将指定目录标记......
  • Linux - centos6忘记root密码怎么办?
     Linux的root密码修改不像Windows的密码修改找回,Windows的登录密码忘记需要介入工具进行解决。CentOS6和CentOS7的密码方法也是不一样的,具体如下 1、开机按esc 2、按e键进入编辑模式 3、进入该编辑模式后,在quiet后面输入simple或者1然后回车 4、按b键进......
  • Linux shell command make & Makefile All In One
    Linuxshellcommandmake&MakefileAllInOne脚本自动化构建工具make&makefilehttps://linux.xgqfrms.xyz/linux_basic/1010index.htmmake第二十二章、1.3https://linux.xgqfrms.xyz/linux_basic/0520source_code_and_tarball.htm#intro_makemakefile第二十二章、......
  • linux 清空文件内容的方式
    一、通过重定向来清空文件内容->通过shell重定向null到指定文件即可>access.log->重定向:或true到指定文件:>access.logtrue>access.log二、使用cat/cp/dd使用工具和/dev/null设备来清空文件内容ps:/dev/null是特殊文件,它将清空重定向到它的输出,而它输入是空白文件,......
  • Linux-RHCA操作系统
    shell命令概述Shell作用:命令解释器介于操作系统内核与用户之间,负责解释命令行获得命令帮助内部命令help命令的“--help”选项使用man命令阅读手册页命令行编辑的几个辅助操作Tab键:自动补齐反斜杠“\”:强制换行快捷键Ctrl+U:清空至行首快捷键Ctrl+K:清空至行尾快捷键Ctr......
  • Compile NSIS scripts in Linux
    http://blog.alejandrocelaya.com/2014/02/01/compile-nsis-scripts-in-linux/ CompileNSISscriptsinLinuxNSISisawellknownsystemusedtocreateWindowsinstallersforanytypeofapplicationbasedonscripts.Itisgoodsystem.Oncewehavedefinedour......
  • Linux开发
    shell命令概述Shell作用:命令解释器介于操作系统内核与用户之间,负责解释命令行获得命令帮助内部命令help命令的“--help”选项使用man命令阅读手册页命令行编辑的几个辅助操作Tab键:自动补齐反斜杠“\”:强制换行快捷键Ctrl+U:清空至行首快捷键Ctrl+K:清空至行尾快捷键Ctr......
  • Windows 11 和 Rocky 9 Linux 平台 MySQL 8.0.33 简易安装教程
    目录Windows平台安装MySQLLinux平台Rocky9安装MySQLbinarypackagerpmpackageyum源sourcepackageWindows11和Rocky9Linux初体验MySQL8.0.33简易安装教程。MySQL8.0目前最新稳定版本已经更新到了MySQL8.0.33,估计下一个稳定版本(大约在今年7月份)推出。当然,......
  • python生成13位或16位时间戳以及反向解析时间戳
    importdatetimeimporttimedefget_float_time_stamp():datetime_now=datetime.datetime.now()returndatetime_now.timestamp()defget_time_stamp16():#生成16时间戳eg:1540281250399895-lndatetime_now=datetime.datetime.now()print(datetim......