系统调用
C标准函数和系统调用关系。一个hello world 如何打印到屏幕上
Open函数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
参数:
pathname:欲打开的文件路径名
flags:文件打开方式 O_RDONLY、O_WRONLY、O_RDWR、O_CREAT
O_APPEND、O_TRUNC
int open(const char *pathname, int flags, mode_t mode);
参数:
pathname:欲打开的文件路径名
flags:文件打开方式 O_RDONLY、O_WRONLY、O_RDWR、O_CREAT
O_APPEND、O_TRUNC
Mode:参数flags使用 O_CREAT 的前提下 ,取八进制数,用来描述文件的访问权限
这里的文件的访问权限与操作系统的umask的掩码有关
八进制数对应原则: W:2 R:4 X:1
例子:
当前环境下文件掩码位0002
当前执行代码 设置文件属性为0777
创建出来的文件属性为 0775
操作系统版本不同 以前的操作系统默认创建出来的文件没有内容对应的也就没有操作权限 所以 在设置mode位时 经常使用0664
函数返回值:
成功:打开文件所得到的对应的文件描述符(3、4、5.......)
原因:因为系统默认打开:标准错误、标准输入、标准输出
失败:-1,设置errno
Close函数 关闭文件
int close(int fd);
错误处理函数
标准写法:printf("xxxxx error:%s\n", strerror(errno));
便捷写法:perror("xxxx error\n");
Read函数
ssize_t read(int fd, void *buf, size_t count);
参数:
fd:读文件所对应的文件描述符
Buf:存数据的缓冲区
Count:缓冲区大小
返回值:
成功:读到的字节数
失败:-1
a)如果errno == EAGIN/EWOLDBLOCK 说明不是read失败,而是read在以非阻塞方式读一个设备文件\网络文件,并且文件无数据
b)失败返回 -1 设置 errno
Write函数
ssize_t write(int fd, const void *buf, size_t count);
参数:
fd:对应的文件描述符
const buf:待写出数据的缓冲区
count:实际写出内容的大小
返回值:
成功:写入的字节数
失败:-1
提出问题:fpuc和write 读写速度比较
fputc:
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <pthread.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 int main(int argc, char *argv[])
9 {
10 int ret;
11 int fd_in, fd_out;
12
13 char buf[1];
14 fd_in = open("./serve.c", O_RDONLY);
15 fd_out = open("./out", O_RDWR | O_CREAT | O_TRUNC, 0644);
16
17 while(ret = read(fd_in, buf, sizeof(buf))) {
18 write(fd_out, buf, ret);
19 }
20
21 close(fd_in);
22 close(fd_out);
23 return 0;
24
25 }
26
~
运行结果:
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 4096) = 4096
read(3, "\tser_addr.sin_port = htons(SER_P"..., 4096) = 4096
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 4096) = 4096
read(3, "(SER_PORT);\n\tser_addr.sin_addr.s"..., 4096) = 4096
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 4096) = 4096
read(3, "dr = htonl(INADDR_ANY);\n\tlfd = S"..., 4096) = 4096
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 4096) = 4096
read(3, "_SET(lfd, &allset);\n\twhile(1) {\n"..., 4096) = 4096
write(4, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 4096) = 4096
write:
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <pthread.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 int main(int argc, char *argv[])
9 {
10 int ret;
11 int fd_in, fd_out;
12
13 char buf[1];
14 fd_in = open("./serve.c", O_RDONLY);
15 fd_out = open("./out", O_RDWR | O_CREAT | O_TRUNC, 0644);
16
17 while(ret = read(fd_in, buf, sizeof(buf))) {
18 write(fd_out, buf, ret);
19 }
20
21 close(fd_in);
22 close(fd_out);
23 return 0;
24
25 }
26
运行结果:
write(4, "r", 1) = 1
read(3, "g", 1) = 1
write(4, "g", 1) = 1
read(3, "v", 1) = 1
write(4, "v", 1) = 1
read(3, "[", 1) = 1
write(4, "[", 1) = 1
read(3, "]", 1) = 1
write(4, "]", 1) = 1
read(3, ")", 1) = 1
write(4, ")", 1) = 1
........
分析:为什么同时设置读一个写一个 在系统调用过程中 fputc却是一次写4096 而write 一次写1个
结论:预读入缓输出机制
write函数运行的时间比fputc函数时间长得多 原因在于 write 频繁地系统调用 从用户到内核的跨域消耗了太长的时间
fputc有一个自己的buf 当自己的buf写满之后在进行系统调用 节省了大部分时间
预读入缓输出机制