Linux-linux系统函数
linux系统函数
linux系统函数
1.Linux函数简述
Linux系统函数
的用法必须结合Linux内核
的工作原理 来理解,因为系统函数
正是内核提供给应用程序
的接口,而要理解内核的工作原理,必须熟练掌握C语言
,因为内核也是用C语言写的。- 我们在描述
内核工作原理
时必然要用“指 针
”、“结构体
”、“链表
”这些名词来组织语言,就像只有掌握了英语才能看懂英文书一样,只有学好了C语言
才能看懂我描述的内核工作原理。
2.文件I/O
2.1-C标准库函数和系统函数的关系
2.2文件描述符
文件描述符
在形式上是一个非负整数
。实际上,它是一个索引值
,指向内核为每一个进程
所维护的该进程打开文件的记录表
。当程序打开
一个现有文件或者创建
一个新文件时,内核向进程返回一个文件描述符。
一个进程默认打开3个文件描述符:
STDIN_FILENO 0
STDOUT_FILENO 1
STDERR_FILENO 2
标准输入(STDIN_FILENO)的文件描述符是 0
标准输出(STDOUT_FILENO )的文件描述符是 1
标准错误(STDERR_FILENO )的文件描述符是 2。
- 新打开文件返回文件描述符表中
未使用
的最小
文件描述符。 - 文件描述符的有效范围是
0
到OPEN_MAX
。一般来说,每个进程最多可以打开64
个文件(0 — 63)。
2.3-task_struct结构体
- 为了
管理进程
,操作系统必须对每个进程
所做的事情进行清楚的描述,为此,操作系统使用数据结构
来代表处理不同的实体,这个数据结构就是通常所说的进程控制块
(PCB
)。 - 在
linux
操作系统下这就是task_struct结构体
,所属的头文件#include <sched.h>
每个进程都会被分配一个task_struct结构,它包含了这个进程的所有信息
。
这个进程的主要信息:
-
1、与进程相关的唯一标识符:区别正在执行的进程和其他进程
-
2、状态:描述进程的状态,因为进程有阻塞、挂起、运行等好几个状态,所以都有个表示符来记录进程的执行状态。
-
3、优先级:如果有好几个进程正在执行,就涉及到进程的执行的先后顺序,这和进程的优先级这个标识符有关。
-
4、程序计数器:程序中即将被执行指令的下一条地址。
-
5、内存指针:程序代码和进程相关数据的指针。
-
6、上下文数据:进程执行时处理器的寄存器中的数据。
-
7、I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
-
8、记账信息:包括处理机的时间总和,记账号等等
2.4-files_struct结构体
files_struct结构体
定义在include/linux/fs.h
中定义。文件结构体代表一个打开的文件
,系统中的每个打开的文件在内核空间都有一个关联的 files_struct
。- 它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核创建和驱动源码中,
files_struct
的指针通常被命名为file
或filp
。
2.5-文件描述符、task_struct结构体(PBC)、files_struct结构体三者关系
文件描述符fd
只是一个小整数,在open
时产生。起到一个索引
的作用,进程通过PCB
中的文件描述符表找到该fd
所指向的文件指针filp
。·- 文件描述符的操作(如:
open
)返回的是一个文件描述符
,内核会在每个进程空间中维护一个文件描述符表
,所有打开的文件都将通过此表中的文件描述符来引用;而流(如:fopen
)返回的是一个FILE结构指针
, FILE结构是包含有文件描述符的,FILE结构函数
可以看作是对fd
直接操作的系统调用的封装, 它的优点是带有I/O缓存
。 - 每个进程在
PCB
即进程控制块
中都保存着一份文件描述符
表,文件描述符就是这个表的索引,文件描述表中每个表项都有一个指向已打开文件的指针
,已打开的文件在内核中用file结构体
表示,文件描述符表中的指针指向file结构体
。
2.6-open函数 open函数
有两种形式,一种带两个参数,一种带三个参数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
返回值:成功返回新分配的文件描述符,出错返回-1并设置errno
pathname参数
是要打开或创建的文件名,和fopen
一样,pathname
既可以是相对路径
也可以是绝对路径
。flags参数
有一系列常数值可供选择,可以同时选择多个常数用按位或
运算符连接起来,所以这些常数的宏定义都以O_
开头,表示or
。
flag参数选项:
必选项:以下三个常数中必须指定一个,且仅允许指定一个。
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 可读可写打开
可选项:以下可选项可以同时指定0个或多个
,和必选项按位或起来作为flags参数。可选项有很多, 这里只介绍一部分。
O_APPEND
表示追加。如果文件已有内容,这次打开文件所写的数据附加到文件的末尾 而不覆盖原来的内容。O_CREAT
若此文件不存在则创建它。使用此选项时需要提供第三个参数mode,表示该 文件的访问权限。O_EXCL
如果同时指定了O_CREAT,并且文件已存在,则出错返回。O_TRUNC
如果文件已存在,并且以只写或可读可写方式打开,则将其长度截断(Trun- cate)为0字节。O_NONBLOCK
对于设备文件,以O_NONBLOCK方式打开可以做非阻塞I/O(Nonblock I/ O)
2.7-close函数
close函数关闭一个已打开的文件:
#include <unistd.h> int close(int fd);
返回值:成功返回0,出错返回-1并设置errno
参数fd
是要关闭的文件描述符
。需要说明的是,当一个进程终止
时,内核对该进程所有尚未关闭
的文件描述符调用close关闭,所以即使用户程序不调用close
,在终止时内核也会 自动关闭它打开的所有文件。但是对于一个长年累月运行的程序
(比如网络服务器),打开 的文件描述符一定要记得关闭,否则随着打开的文件越来越多,会占用大量文件描述符和系统资源。
参考文章:
https://www.cnblogs.com/pluslius/p/10088929.html
https://blog.csdn.net/daboluo521/article/details/79598281
https://www.cnblogs.com/hanxiaoyu/p/5677677.html