man 2 stat stat函数
stat day12.txt 查看文件状态信息
struct stat sbuf;
求文件大小 sbuf.st_size
ls -i test.txt 可以查找inode号
注意:指针前面没有加const,就表示该指针是个传出型参数。
存储文件时,除了文件本身以外,还会存储文件的属性(权限,拥有者,时间)等基本信息。
文件系统
文件系统是OS管理持久性数据的子系统,提供数据存储和访问的功能。
文件系统中的基本单位就是数据块。
超级块(磁盘分区以及文件系统描述信息)、索引块(inode,访问权限,拥有者,大小)、目录项构成一棵目录树、 磁盘上的数据块
索引块中保存数组下标就是inode号,inode指向文件所使用的数据块列表(链表存放),这样就可以在数据区查找数据。
我们查看文件信息时,是按照文件名去查找的,而OS会先查找文件所在的目录,通过目录中保存的表格查找到文件的inode号,
然后OS再通过文件名对应的inode号去索引块中查找inode号对应的数据区的编号。
实际上,每个目录就是一张表,这张表中存储了文件名和其对应的inode号之间的映射关系,最终构成了一棵目录树。
一些文件系统提供文件锁,用于协调多进程的文件访问。
强制
根据锁保持情况和访问需求确定是否拒绝访问
劝告
进程可以查找锁的状态来决定该怎么做
索引分配
为每个文件创建一个索引数据块,指向文件数据块的指针列表,文件头包含了索引数据块指针
当文件小时,采用直接索引的方式,当文件大时,采用多级链式索引的方式.
根分区是采用了硬编码的方式写进去的
ls -ldi / 是2 根分区的索引是采用硬编码的方式写死的。
硬链接: ln 源文件名 硬链接文件名 eg: ln abc abc.h
执行ls -l命令后,出现在权限后面的数字就是硬链接数 (有几个文件名对应着同一个inode)
文件所有者的权限,文件所属组的权限 和 其他用户对文件的权限
目录的硬链接数至少是2(一个在当前目录的父目录中保存,一个在当前目录下面保存)
如果删除硬链接,那么数字减1,直到数字减为0后,磁盘才会删除掉这个文件。(引用计数)
硬链接应用
备份 只是inode指向同一个文件,并不是真正的拷贝文件,不占用磁盘空间。 cp需要分配空间去复制
ln Makefile .Makefile 创建一个硬链接(并且是隐藏文件.),这时如果删除了Makefile,也没事,最多只是引用计数减去1。
需要注意的是,Windows上没有硬链接,有软链接,而Linux上既有硬链接还有软链接(也就是快捷方式)。
例如不能ln haha mnt/hgfs/shared/hehe
硬链接不能跨分区
也就是说C盘不能访问D盘的硬链接 例如不能ln haha mnt/hgfs/shared/hehe
软链接:ln -s 源文件名 软链接文件名
软链接可以跨分区,实际上软链接就是个路径。
acm
Access 最后访问时间
Change 属性最后修改时间
Modify 文件内容最后修改时间
库:
静态库 对一系列.o文件打包
交给客户 .o以及.h文件
需要进行编译。
首先生成.o文件(gcc -c )
接着生成静态库 ar -cr lib库名.a *.o (文件) 库名 :去头掐尾留中间
最后使用静态库 gcc main.c -L . -l库名 (.表示当前路径) 非官方的写法 gcc main.c libmath.a
(.表示库路径)
寻找库/lib –> /usr/lib –> /usr/local/lib
将生成的库放在上述路径下面也可以。
安装软件时需要root权限,是因为要把相关软件的库放在上述路径下面,只有root权限才允许这样做。
如果删除了已经生成的静态库,并不会影响到可执行文件的运行,查看机器码即可发现代码已经被插进去了。
objdump命令是用来查看目标文件或者可执行的目标文件的构成的gcc工具。
objdump -dS a.out 查看a.out的反汇编机器码
使用静态库的好处:运行速度快。
静态库的缺陷:
当多个进程都要使用到某个静态库时,那么每一次都会在物理内存中开辟一片空间来存放(相同的机器码),这样会造成极大的资源浪费。
动态库(共享库 shared library) 共享存储映射区
需要注意的是:
将库中的机器码(只读)或者说符号信息存到物理内存中,只需要存储一份即可,哪个进程需要使用该库,
就将存储的内容通过三级映射最后映射到进程的虚拟内存中。
使用动态库好处:节省内存空间,可以实现平滑升级。
动态库没有添加代码进去,nm查看没有地址,动态库只是将符号信息存进去。
如果同时有静态库和动态库,优先选择动态库。
运行时才添加动态库
常见的ELF文件
a.out .o文件 coredump产生的core文件 .so文件
可重定位文件(relocatable) : linux下的.o文件,windows下的.obj文件
可执行文件(executable) : linux下的/bin/bash文件或者a.out,windows下的.exe文件
共享目标文件(shared object) : linux下的.so文件,windows下的.dll文件
核心转储文件(core dump) :linux下的core dump 段错误
生成动态库
1》gcc -fPIC -shared -o lib库名.so xxx.c (PIC 位置无关的代码)如果不加上PIC可能会导致在其他机器上运行出错。
-shared -o后面加的是动态库文件名
file XXX.so查看文件类型
file libmath.a 该文件是个归档文件
链接动态库
2》gcc main.c -L. -lmymath
使用动态库
如果没有配置的话,会出现下面的问题
ldd a.out 动态库文件找不到
ldd命令用来查看都装了哪些动态库
ldd -u a.out查看不需要链接的so文件
linux-vdso.so.1 => (0x00007ffe625d2000)
libmath.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcbe0612000) 标准C库链接
/lib64/ld-linux-x86-64.so.2 (0x00007fcbe09dc000) 动态链接器
3》
1./lib
/usr/lib
2. LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
export LD_LIBRARY_PATH
export LD_LIBRARY_PATH=.
执行结果 ldd a.out
libmath.so => ./libmath.so (0x00007f255461f000)
3.推荐使用
/etc/ld.so.conf.d/xxx.conf 文件中将动态库的路径写入
echo `pwd` > /etc/ld.so.conf.d/my.conf 将当前路径写入动态库 (``命令替换)
4. ldconfig 使用该命令可以让动态链接库为系统所共享。 必须在root权限下使用
-p输出缓存文件/etc/ld.so.cache中的动态链接库列表,同时也会输出共享库的名字及其绝对路径。
-v显示正在扫描的目录及搜索到的共享库。
执行结果 ldd a.out
libmath.so => /home/zc/C_test/mk_test/lib/libmath.so (0x00007fb7a7d3f000)
qq平滑升级正是利用了动态库,替换掉之前的动态库文件即可。
升级过程中不能中断,如果替换动态库文件出了问题,就会导致升级失败。
动态库的运行时处理
dlopen()
进程间通信(IPC)
目的:
数据传输 (消息队列)
资源共享 (共享内存)
通知事件 kill pid(信号量)
进程控制 gdb
管道
最古老的进程间通信方式(半双工)
单工 :广播
半双工 : 对讲机
全双工 : 打电话
| 管道,本质,内核中开辟的一块缓存
特点:一个进程可以往里面写 另外一个进程可以从里面读 读写必须同时进行
int pipe(int fds[2]);
fds:文件描述符数组,其中fds[0]表示读端(读取数据来自管道), fds[1]表示写端(将数据写到管道里面)
成功返回0,失败返回-1
子进程往管道里面写数据,由于fork出子进程后,引用计数会加1,那么在写数据时,就需要关掉一个,并且写的时候不能读。
父进程从管道里面读数据,由于fork出子进程后,引用计数会加1,那么在读数据时,就需要关掉一个,并且读的时候不能写。
过程讲解:首先,内核会开辟出来一个管道缓存用来临时存放数据(pipe(fds)),由于管道中读写数据必须同时进行,
而父进程fork出一个子进程,刚好满足这种需求。
子进程要往管道里面写数据,
那么就需要保证子进程不能在管道中读取数据close(fds[0]),然后子进程往管道中写入数据write(fds[1], "123", 3),
子进程写完数据后,暂时不再需要写入数据,就把子进程的写端关闭close(fds[1])。
父进程从管道里面读取数据,
那么就需要保证父进程不能在管道中写数据close(fds[1]),然后父进程开始从管道中读取数据read(fds[0], buf, 100),
父进程读取完数据后,暂时不会再读取数据,就把父进程的读端关闭close(fds[0])。
硬盘中真实存在的文件:普通文件、目录文件、软链接文件(快捷方式)
|
SystemV IPC
消息队列(数据传输)
共享内存(数据共享)
信号量(事件通知)
|
POSIX IPC
消息队列
共享内存
互斥量
条件变量
信号量
读写锁
介绍下进程间通信的方式
管道、读写文件 网络通信