系统调用是操作系统提供给用户的一组“特殊”接口,用户程序可以通过这组接口获取操作系统(内核)提供的服务。
系统调用按照功能逻辑大体分为哪几部分?
进程控制、进程间通信、文件系统控制、系统控制、内存管理、网络管理、socket控制、用户管理
系统调用号的作用?
操作系统给每个系统调用分配了一个唯一的编号,这个编号就是系统调用号。用户空间进程执行一个系统调用时,这个系统调用号就被用来指明执行哪个系统调用。
系统调用号一旦分配就不能变更,此外,如果一个系统调用被删除,它所占用的系统调用号也不允许被回收利用。
库函数与系统调用的关系?
库函数调用是在用户态下,运行在用户空间。
系统调用是操作系统的一部分,是内核提供给用户进行核心态的入口,运行在内核空间。
库函数有两种,一是不需要调用系统调用的,二是需要调用系统调用的。
并不是所有的系统调用都被封装成了库函数,系统提供的很多功能都必须通过系统调用才能实现。
调用系统调用函数与库函数各自有什么优缺点?
系统调用是需要时间的,频繁调用会降低程序的运行效率。
当运行内核代码时,CPU工作在内核态,在系统调用发生前需要保存用户态的栈和内存环境,然后转入系统台态工作。
系统调用结束后,又要切换回用户态。这种环境的切换会消耗很多时间。
而库函数,访问文件时根据需要,设置不同类型的缓冲区,减少了直接调用IO系统调用的次数,提高了访问效率。
使用系统调用函数编程,实现文件的复制(类似Linux命令cp),例如生成的可执行程序为app,运行程序时:./app a.txt b.txt将a.txt文件内容复制到b.txt文件中
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("argc error");
exit(0);
}
int fdr = open(argv[1], O_RDONLY);
assert(fdr != -1);
int fdw = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0064);
assert(fdw != -1);
while(1) {
char buff[128] = {0};
int n = read(fdr, buff, 127);
assert(n != -1);
if (n == 0) {
break;
}
int num = write(fdw, buff, n);
assert(num != -1);
}
close(argv[1]);
close(argv[2]);
return 0;
}