libc、系统调用与内核接口
结论速览
- 典型调用链是应用程序、libc/POSIX API、syscall、Linux Kernel,
write()由 libc 提供用户态包装后进入内核。 - 文件、网络、进程、内存、设备控制都有对应的常见接口:
open/read/write、socket/connect、fork/execve、mmap、ioctl。 strlen、strcmp、memcpy完全在用户空间完成,不进内核;C 标准库函数和 Linux 系统调用不是一回事。- 头文件只提供函数声明、结构体、宏、常量和类型,真正功能由 libc 和 Kernel 共同完成。
- Linux 的接口不只是 syscall:
/dev、/proc、/sys里的文件同样是访问内核的接口。
1. 用户程序如何使用 Kernel
典型调用链:
1 | 应用程序 |
例如:
1 | write(fd, buf, len); |
通常由 libc 提供用户态包装,然后进入内核。
2. 常见接口
文件:
1 | open() |
网络:
1 | socket() |
进程:
1 | fork() |
内存:
1 | mmap() |
设备控制:
1 | ioctl() |
3. 不是所有 libc 函数都会进入 Kernel
例如:
1 | strlen() |
通常完全在用户空间完成。
而:
1 | read() |
需要 Kernel 提供对应系统调用。
因此:
1 | C 标准库函数 |
和:
1 | Linux 系统调用 |
不是一回事。
4. 头文件告诉你 API 怎么使用
例如 socket 程序:
1 |
头文件提供:
1 | 函数声明 |
但真正的功能由 libc 和 Kernel 共同完成。
5. 怎么查接口文档
Linux 上常用:
1 | man 2 socket |
其中:
1 | man 2 |
6. /dev、/proc、/sys 也是接口
Linux 并不只有 syscall。
用户空间还经常通过:
1 | /dev/* |
访问内核。
例如:
1 | /dev/ttyS0 |
代表串口设备接口。
1 | /proc/cpuinfo |
暴露 CPU 信息。
1 | /sys/class/net/ |
暴露网络设备对象。
所以 Linux 应用看到的「接口」可能是:
1 | 函数 |
