首页 文章 02_系统调用

02_系统调用

2024-04-24 08:37  浏览数:312  来源:拼搏百天我要上蓝翔    

知识点1【系统调用】1、系统调用的概述系统调用: 就是内核 提供给用户可以操作内核 一组函数接口。用户 借助
系统调用 操作内核。进程的空间分为:内核空间 和 用户空间2、系统调用和库函数有啥区别系统调用 是内核提供的一
组函数接口。 内核提供库函数 是第三方的函数接口。 用户提供如果库函数没有调用 系统调用 该库函数不能操作 内
核 比如:字符串操作函数strcpy,bzero如果库函数 调用 系统调用 该库函数 能操作 内核 比如:fo
pen fclose fwrite fgets系统调用是需要时间的,程序中频繁的使用系统调用会降低程序的运行效
率。当运行内核代码时,CPU工作在内核态,在系统调用发生前需要保存用户态的栈和内存环境,然后转入内核态工作。系
统调用结束后,又要切换回用户态。这种环境的切换会消耗掉许多时间。3、C库中IO函数工作流程知识点2【文件描述符
】(重要)Linux将系统调用 打开或新建的文件 用非负整数 来表示。而这个非负整数 就是文件描述符。系统会为
每一个进程 分配文件描述符表,管理该进程的所有文件描述符。系统会为 每一个进程 打开三个文件描述符:0,1,2
0:标准输入设备(键盘) scanf1:标准输出设备(终端)printf2:标准错误输出 (终端)perror
1、文件描述符表是如何管理文件描述符的呢?文件描述符表 是通过 “位图” 来管理文件描述符。使用1024位二进
制位管理,位数代表的就是文件描述符,位上的值1表示打开,值0表示关闭。2、查看当前系统文件描述符最大数量查看:
ulimit -a修改:ulimit -n 20483、文件描述的案例知识点3【文件IO的操作】文件常用操作I
O:open close read write1、打开文件 open1 #include <sys/types
。h>2 #include <sys/stat。h>3 #include <fcntl。h>4 //两个参数的
open用于 打开已存在的文件5 int open(const char *pathname, int fla
gs);6 //三个参数的open用于 打开不存在的文件 mode就是文件在磁盘上的权限7 int open(
const char *pathname, int flags, mode_t mode);功能:打开文件,如
果文件不存在则可以选择创建。参数:pathname:文件的路径及文件名flags:打开文件的行为标志,必选项
O_RDONLY, O_WRONLY, O_RDWRmode:这个参数,只有在文件不存在时有效,指新建文件时指
定文件的磁盘权限返回值:成功:成功返回打开的文件描述符失败:-11、flags 文件的操作权限(read wr
ite)取值 含义O_RDONLY 以只读的方式打开O_WRONLY 以只写的方式打开O_RDWR 以可读、可
写的方式打开可选项,和必选项按位或起来取值 含义O_CREAT 文件不存在则创建文件,使用此选项时需使用mod
e说明文件的权限O_EXCL 如果同时指定了O_CREAT,且文件已经存在,则出错O_TRUNC 如果文件存在
,则清空文件内容O_APPEND 写文件时,数据添加到文件末尾O_NONBLOCK 对于设备文件, 以O_NO
NBLOCK方式打开可以做非阻塞I/O2、mode文件在磁盘的用户权限磁盘文件的用户权限分类:所有拥有者权限(
u)、同组用户权限(g)、其他用户权限(o)任何权限都分为:读(4)、写(2)、执行(1) 这3个数值可以组合
7--->可读可写可执行 6--->可读可写 5--->可读可执行 4--->只读3--->可写可执行 2--
->只写 1--->可执行mode的权限表示0xxx 每一个x都是(4,2,1)的组合0777 所有者、同组用
户、其他用户都是可读可写可执行0666 所有者、同组用户、其他用户都是可读可写0651 所有者可读可写 、同组
用户可读可执行、其他用户可执行3、mode的系统掩码查看掩码:umask文件的最终权限=给定的权限 & ~um
askumask mode:设置掩码,mode为八进制数umask -S:查看各组用户的默认操作权限2、clo
se关闭文件描述符1 #include <unistd。h>2 int close(int fd);功能:关闭
已打开的文件参数:fd : 文件描述符,open()的返回值返回值:成功:0失败: -1, 并设置errno注
意:close工作步骤,先将文件描述符的数量-1,当文件描述符的数量变为0的时候 ,系统回收文件描述符所占的内
核空间。3、向文件写数据write1 #include <unistd。h>2 ssize_t write(i
nt fd, const void *buf, size_t count);功能:把指定数目的数据写到文件(f
d)参数:fd : 文件描述符buf : 数据首地址count : 写入数据的长度(字节)返回值:成功:实际写
入数据的字节个数失败: - 1案例1:写入数据1 #include <stdio。h>2 #include <
unistd。h>3 #include <string。h>4 #include <sys/types。h>5
#include <sys/stat。h>6 #include <fcntl。h>7 int main(in
t argc, char const *argv[])8 {9 int fd = open("b。txt",
O_WRONLY | O_CREAT, 0666);10 if (fd < 0)11 {12 perror("
open");13 return 0;14 }15 printf("fd = %d\n", fd);1617
//写入文件数据18 char buf[128] = "";19 fgets(buf, sizeof(buf)
, stdin);20 buf[strlen(buf) ‐ 1] = 0;2122 write(fd, buf
, strlen(buf));2324 //关闭文件25 close(fd);26 return 0;27 }
4、read读取文件数据1 #include <unistd。h>2 ssize_t read(int fd,
void *buf, size_t count);功能:把指定数目的数据读到内存(缓冲区)参数:fd : 文
件描述符buf : 内存首地址count : 读取的字节个数返回值:成功:实际读取到的字节个数读完文件数据返回
0失败: - 11 #include <stdio。h>2 #include <unistd。h>3 #inc
lude <string。h>4 #include <sys/types。h>5 #include <sys/
stat。h>6 #include <fcntl。h>7 int main(int argc, char co
nst *argv[])8 {9 int fd = open("b。txt", O_RDONLY);10 if
(fd < 0)11 {12 perror("open");13 return 0;14 }15 print
f("fd = %d\n", fd);1617 //读取文件数据18 char buf[128] = "";1
9 int len = read(fd, buf, sizeof(buf));20 printf("读取的内容
%s, 长度:%d\n", buf, len);2122 //关闭文件23 close(fd);24 retu
rn 0;25 }1 ssize_t read(int fd, void *buf, size_t count
);2 ssize_t write(int fd, const void *buf, size_t count
);5、综合案例:实现cp命令1 cp b。txt test 将b。txt文件拷贝到test目录中1 #inc
lude <stdio。h>2 #include <unistd。h>3 #include <sys/type
s。h>4 #include <sys/stat。h>5 #include <fcntl。h>6 int ma
in(int argc, char const *argv[])7 {8 //判断参数是否正确(。/a。out
b。txt test)9 if (argc != 3)10 {11 printf("。/a。out b。tx
t test\n");12 return 0;13 }1415 //以只读的方式 打开b。txt文件16 in
t fd_r = open(argv[1], O_RDONLY);17 if (fd_r < 0)18 {19
perror("open");20 return 0;21 }2223 //以写的方式 在test目录中打开
b。txt24 char file_name[32] = "";25 //test/b。txt26 sprin
tf(file_name, "%s/%s", argv[2], argv[1]);27 int fd_w =
open(file_name, O_WRONLY | O_CREAT, 0666);28 if (fd_w <
0)29 {30 perror("open");31 return 0;32 }3334 //不同的从fd_
r中读取文件数据 写入fd_w文件中35 while (1)36 {37 unsigned char buf[
128] = "";38 int len = read(fd_r, buf, sizeof(buf));39
if (len <= 0)40 break;4142 write(fd_w, buf, len);43 pri
ntf("len=%d\n", len);44 }4546 //关闭文件47 close(fd_r);48 c
lose(fd_w);4950 return 0;51 }知识点4【文件的阻塞特性】阻塞和非阻塞 针对的是文件
描述符 而不是read write函数文件描述符 默认 为阻塞的。1、通过open函数 在打开文件的时候 设置
文件描述符为非阻塞。文件描述符 事先不存在 才是用open案例1:open打开文件 默认为阻塞特性案例2:op
en打开文件 设置为非阻塞特性2、通过fcntl设置文件的阻塞特性文件描述符 事先存在1 #include <
unistd。h>2 #include <fcntl。h>3 int fcntl(int fd, int cm
d, 。。。 /* arg */ );功能:改变已打开的文件性质,fcntl针对描述符提供控制。参数:fd:操
作的文件描述符cmd:操作方式arg:针对cmd的值,fcntl能够接受第三个参数int arg。返回值:成功
:返回某个其他值失败:-1fcntl函数有5种功能:1) 复制一个现有的描述符(cmd=F_DUPFD)2)
获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)3) 获得/设置文件状态标记(cmd=F_G
ETFL或F_SETFL)4) 获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)5)
获得/设置记录锁(cmd=F_GETLK, F_SETLK或F_SETLKW)设置一个存在的文件描述符的阻塞特
性的步骤1、fcntl获取文件描述符的状态标记2、修改 获取到的 文件描述符的状态标记3、将修改后的状态标记
使用fcntl设置到文件描述符中案例1:设置一个存在的文件描述符的阻塞特性知识点5【获取文件的状态信息】1 #
include <sys/types。h>2 #include <sys/stat。h>3 #include
<unistd。h>4 int stat(const char *path, struct stat *buf
);5 int lstat(const char *pathname, struct stat *buf);功
能:获取文件状态信息stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息
;而stat返回的是该链接指向的文件的信息。参数:path:文件名buf:保存文件信息的结构体返回值:成功:
0失败: -1struct stat结构体说明:1 struct stat {2 dev_t st_dev;
//文件的设备编号3 ino_t st_ino; //节点4 mode_t st_mode; //文件的类型和
存取的权限5 nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为16 uid_t
st_uid; //用户ID7 gid_t st_gid; //组ID8 dev_t st_rdev; //
(设备类型)若此文件为设备文件,则为其设备编号9 off_t st_size; //文件字节数(文件大小)10
blksize_t st_blksize; //块大小(文件系统的I/O 缓冲区大小)11 blkcnt_t
st_blocks; //块数12 time_t st_atime; //最后一次访问时间13 time_t
st_mtime; //最后一次修改时间14 time_t st_ctime; //最后一次改变时间(指属性
)15 };st_mode(16位整数)参数说明 :案例1:获取文件的属性、大小1 void test03()
2 {3 //获取文件的状态信息4 struct stat s;5 stat("b。txt", &s);67
//分析文件类型(重要)8 if (S_ISREG(s。st_mode))9 {10 printf("为普通文
件\n");11 }12 else if (S_ISDIR(s。st_mode))13 {14 printf(
"为目录文件\n");15 }1617 //获取文件的权限18 if ((s。st_mode & S_IRUS
R) == S_IRUSR)19 {20 printf("所拥有者具备读权限\n");21 }22 if ((
s。st_mode & S_IWUSR) == S_IWUSR)23 {24 printf("所拥有者具备写权
限\n");25 }26 if ((s。st_mode & S_IXUSR) == S_IXUSR)27 {2
8 printf("所拥有者具备执行权限\n");29 }30 }知识点6【文件目录操作】(重要)1、得到文件
目录的句柄1 #include <sys/types。h>2 #include <dirent。h>3 DIR
*opendir(const char *name);4 功能:打开一个目录5 参数:6 name:目录名7
返回值:8 成功:返回指向该目录结构体指针9 失败:NULL2、读取目录1 #include <dirent
。h>2 struct dirent *readdir(DIR *dirp);功能:读取目录 调用一次只能读取
一个文件参数:dirp:opendir的返回值返回值:成功:目录结构体指针失败:NULL相关结构体说明:1 s
truct dirent2 {3 ino_t d_ino; // 此目录进入点的inode4 off_t d_
off; // 目录文件开头至此目录进入点的位移5 signed short int d_reclen; //
d_name 的内容长度, 不包含NULL 字符6 unsigned char d_type; // d_t
ype 所指的文件类型7 char d_name[256]; // 文件名8 };d_type相关数据:3、关
闭目录1 #include <sys/types。h>2 #include <dirent。h>3 int c
losedir(DIR *dirp);功能:关闭目录参数:dirp:opendir返回的指针返回值:成功:0失
败:-11 #include <stdio。h>2 #include <sys/types。h>3 #incl
ude <dirent。h>45 int main(int argc, char const *argv[])
6 {7 //1、获取文件目录句柄8 DIR *dir = opendir("。/");9 if (dir =
= NULL)10 {11 perror("opendir");12 return 0;13 }1415 //
2、读取文件16 struct dirent *ret;17 while (ret = readdir(dir
))18 {19 if ((ret‐>d_type & DT_REG) == DT_REG)20 {21 pr
intf("%s是普通文件\n", ret‐>d_name);22 }23 else if ((ret‐>d_
type & DT_DIR) == DT_DIR)24 {25 printf("%s是目录文件\n", ret
‐>d_name);26 }27 }2829 //3、关闭目录句柄



声明:以上文章均为用户自行添加,仅供打字交流使用,不代表本站观点,本站不承担任何法律责任,特此声明!如果有侵犯到您的权利,请及时联系我们删除。

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)