一、知識准備
1、在linux中,一切皆為文件,所有不同種類的類型都被抽象成文件。如:普通文件、目錄、字符設備、塊設備、套接字等
2、當一個文件被進程打開,就會創建一個文件描述符。這時候,文件的路徑就成為了尋址系統,文件描述符成為了字節流的接口
3、相對於普通文件這類真實存在於文件系統中的文件,tcp socket、unix domain socket等這些存在於內存中的特殊文件在被進程打開的時候,也會創建文件描述符。所以"一切皆文件"更准確的描述應該是"一切皆文件描述符"
二、環境准備
組件 | 版本 |
---|---|
OS | CentOS Linux release 7.5.1804 |
三、文件描述符
● 文件描述符是一個抽象索引,它指向普通的文件或者I/O設備
● 文件描述符是一個非負整數,它是連接用戶空間和內核空間紐帶
四、測試
我們來看下進程打開的文件描述符:
[root@localhost tmp]# python
Python 2.7.5 (default, Apr 11 2018, 07:36:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> fd = os.open('test.log' , os.O_RDONLY)
>>> print fd
3
>>>
[1]+ Stopped python
打開一個python的交互控制台,然后以只讀的方式打開了一個文件,並且打印了該文件描述符3
我們將交互界面丟如后台以便於觀察:
[root@localhost tmp]# ps | grep python
10900 pts/1 00:00:00 python
[root@localhost tmp]# lsof -n | grep 10900
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python 10900 root cwd DIR 253,0 4096 16777288 /tmp
python 10900 root rtd DIR 253,0 251 64 /
python 10900 root txt REG 253,0 7216 50394900 /usr/bin/python2.7
python 10900 root mem REG 253,0 174576 73603 /usr/lib64/libtinfo.so.5.9
python 10900 root mem REG 253,0 285240 79288 /usr/lib64/libreadline.so.6.2
python 10900 root mem REG 253,0 28440 50390214 /usr/lib64/python2.7/lib-dynload/readline.so
python 10900 root mem REG 253,0 106070960 50566346 /usr/lib/locale/locale-archive
python 10900 root mem REG 253,0 2173512 54770 /usr/lib64/libc-2.17.so
python 10900 root mem REG 253,0 1139680 54778 /usr/lib64/libm-2.17.so
python 10900 root mem REG 253,0 14872 54804 /usr/lib64/libutil-2.17.so
python 10900 root mem REG 253,0 19776 54776 /usr/lib64/libdl-2.17.so
python 10900 root mem REG 253,0 144792 54796 /usr/lib64/libpthread-2.17.so
python 10900 root mem REG 253,0 1847504 137746 /usr/lib64/libpython2.7.so.1.0
python 10900 root mem REG 253,0 164240 54763 /usr/lib64/ld-2.17.so
python 10900 root mem REG 253,0 26254 16796368 /usr/lib64/gconv/gconv-modules.cache
python 10900 root 0u CHR 136,1 0t0 4 /dev/pts/1
python 10900 root 1u CHR 136,1 0t0 4 /dev/pts/1
python 10900 root 2u CHR 136,1 0t0 4 /dev/pts/1
python 10900 root 3r REG 253,0 0 17560386 /tmp/test.log
由於運行了一個python命令行,pid為10900,為了支撐它的運行,需要獲取一些依賴,包括普通文件、目錄、字符設備等
其中打開了大量的文件描述符,我們來選幾個需要關注的內容:
FD:
cwd: 當前目錄
rtd: 根目錄
txt: 應用程序
mem: 內存映射文件
數字(0,1,2,3): 打開的文件描述符
u.r.w: 文件的權限: 只讀、只寫、讀寫
TYPE:
DIR: 目錄
REG: 普通文件
CHR: 字符設備
進程打開文件之后,會創建文件描述符:
[root@localhost tmp]# ls -l /proc/10900/fd
total 0
lrwx------ 1 root root 64 Nov 13 22:10 0 -> /dev/pts/1
lrwx------ 1 root root 64 Nov 13 22:10 1 -> /dev/pts/1
lrwx------ 1 root root 64 Nov 13 22:10 2 -> /dev/pts/1
lr-x------ 1 root root 64 Nov 13 22:10 3 -> /tmp/test.log
3 -> /tmp/test.log
也和 print fd
返回的3
相一致
五、小結
● 本文演示了進程運行過程中需要的資源都以文件描述符的方式呈現,不管這類資源是普通文件、目錄還是字符設備
● 將所有依賴的資源用文件描述符表述,使用統一的API、工具集等,方便操作系統對資源的管理
六、參考資料
https://en.wikipedia.org/wiki/Everything_is_a_file
https://stackoverflow.com/questions/25140730/what-does-the-fd-column-of-pipes-listed-by-lsof-mean
https://en.wikipedia.org/wiki/File_descriptor
至此,本文結束
在下才疏學淺,有撒湯漏水的,請各位不吝賜教...