系统调用:操作系统内核提供的接口,用户进程主动陷入内核,让内核帮你干活。
库函数:语言/标准库封装好的函数(比如C标准库,C++STL),跑在用户态,很多库函数内部会调用系统调用,但不是全部。
用户态:咱们写程序运行的地方,权限低,不能直接操作硬件,磁盘。
内核态:操作系统内核,权限最高,可以操作硬件,管理进程,文件。
一.系统调用
属于操作系统内核提供服务,不是C/C++语言自带。
执行时会用户态->内核态切换(有开销)。
例子:open,read,write,fork,mmap,getpid。
本质:进程发起中断,请求内核完成任务。
比如read()系统调用:让内核从磁盘/文件把数据读到缓冲区。
二.库函数
在用户态执行,是别人封装好的一段代码,在shturl.这类库里面。
分两类:
1.包装型库函数:内部调用系统调用
例如C库fread/fwrite/fopen。fopen底层会调用系统调用open,还额外加了用户层缓冲。
2.纯计算类库函数:完全不触发系统调用
strlen,memcpy,sqrt,全部在用户空间完成,不进内核。
举例:
// 系统调用,无用户缓冲区 int fd = open("a.txt", O_RDONLY); read(fd, buf, 100); // C库函数,带用户缓冲区,内部封装open/read系统调用 FILE* fp = fopen("a.txt", "r"); fread(buf,1,100,fp);fread不是系统调用,它在用户态先操作stdio缓冲区;缓冲区空了,才调用内核read系统调用拿数据。
三.区别
1.归属
系统调用:内核提供;
库函数:标准库(libc)提供。
2.运行态
系统调用:触发用户态->内核态切换;
库函数:默认用户态,只有内部syscall时才切内核。
3.开销
系统调用开销更大(上下文切换);
库函数大部分逻辑在用户态,开销小。
4.可移植性
系统调用:和操作系统强绑定(Linux和Windows系统调用不一样);
库函数:标准库统一接口,代码可移植。
5.缓冲区
系统调用没有用户层缓冲区;
stdio库函数自带用户缓冲区。