系统调用是操作系统提供给用户的一组“特殊”接口,用户程序可以通过这组接口获取操作系统(内核)提供的服务。

系统调用按照功能逻辑大体分为哪几部分?

进程控制、进程间通信、文件系统控制、系统控制、内存管理、网络管理、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;
}