结合 Go 读 APUE-文件共享

在公众号 "别捉急" 上 同步了文章,并且可以点击原文链接阅读:传送门

文件共享

UNIX 系统支持在不同进程间共享打开文件, 知识点:内核用于所有 I/O 的数据结构、原子操作。

概念性的 I/O 数据结构

内核用于所有 I/O 的数据结构,只是个概念性的,不一定适用,有个大体的轮廓就 OK。

  • 进程表 (process table entry) 中的记录
  • 文件表项 (file table entry)
  • v节点表项 (v-node table entry)
打开文件的内核数据结构

这是一个 打开文件的内核数据结构 图。打开文件 这个操作是一个进程, 每个进程在进程表中都有一个记录,而 打开文件进程记录 中包含一张打开文件描述符表, 包括:

  • 文件描述符标志
  • 指向一个文件表项的指针

文件描述符表用 Go 抽象如下表示:

type fd struct {
    flags   int
    pointer *FileTableEntry
}

代码中 flags 的类型是随便定义的(实际我没查),由图中看出 pointer 指向文件表项 (file table entry), 内核为所有打开文件维持一张文件表, 每个文件表项包括:

  • 文件状态标志 (读、写、添写、同步和非阻塞)
  • 当前文件偏移量
  • 指向该文件 v 节点表项的指针

文件表项用 Go 抽象如下表示:

type FileTableEntry struct {
    status  int
    offset  int
    pointer *VNodeTableEntry
}

由图中看出 pointer 指向v节点表项 (v-node table entry), 每个打开文件都有一个 v 节点结构如下所示:

  • 文件类型和对此文件进行各种操作函数的指针,统称为 v节点信息
  • 该文件的 i 节点: 文件所有者、文件长度、指向文件实际数据块在磁盘上所在位置的指针等

V 节点表项和 i 节点用 Go 抽象如下:

type VNodeTableEntry struct {
    information *Information
    vData       *INode
}

type INode struct {
    owner           *Owner
    length          int
    vNodeTableEntry *VNodeTableEntry
}

通过这种方式,来加深对 内核通用 I/O 数据结构 的理解。

如果两个独立进程各自打开同一个文件,则三者关系如下所示:

两个独立进程打开同一个文件

原子操作

一般而言,原子操作 (atomic operation) 指的是由多步组成的一个操作。如果该操作原子地执行,则要么执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。

函数 dup 和 dup2

下面两个函数都可用来复制一个现有的文件描述符。

#include <unistd.h>

int dup(int fd);

int dup2(int fd, int fd2);

上面函数中的参数:

  • fd 表示要复制的文件描述符
  • fd2 表示复制后的文件描述符

dup2 函数是可以指定复制后的文件描述符,而 dup 是返回当前可用文件描述符中的最小数值。

调用 dup(1) 函数后,进程表项,文件表,v 节点表,之间的关系图如下:

dup(1) 后的内核数据结构

对于传入的参数 fd2, 已经被打开了,会先关闭。知道了这个点,就明白了,下面的操作中会先调用 close(fd2)

很不爽了,没找到相应的 Go 的源码。复制一个描述符的另一种方法是使用 fcntl函数, dup2(fd, fd2) 等效于 close(fd2)fcntl(fd, F_DUPFD, fd2), 但不完全等效,因为 dup2(fd, fd2) 是个原子操作。

目前我先知道 fcntl函数 可以改变已经打开文件的属性,就可以啦。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容