首先需要明确一点:系统调用的具体列表和编号会随着内核版本演进而变化,增加新的调用或废弃旧的调用。虽然核心功能(如文件 I/O、进程管理)相对稳定,但细节上会有差异。请注意,最准确的信息始终来自于查阅对应内核版本的源代码或权威文档。
Linux 3.0 内核系统调用 (基于 x86_64 架构)
Linux 3.0 是一个相对成熟的内核版本。其系统调用接口已经非常丰富和稳定。
系统调用分类与接口
进程控制 (Process Control)
fork(57): 创建一个子进程。vfork(58): 创建子进程,但在子进程调用exec或_exit前阻塞父进程。clone(56): 创建子进程或线程,比fork/vfork更灵活,允许共享内存空间等。execve(59): 用新程序替换当前进程镜像。exit(60): 终止调用进程。exit_group(231): 终止线程组中的所有线程。wait4(61): 等待子进程状态变化。waitid(247): 等待子进程状态变化(提供比wait4更丰富的信息)。kill(62): 发送信号给进程。tkill(200): 发送信号给指定线程 (已废弃,推荐使用tgkill)。tgkill(234): 发送信号给指定进程内的指定线程。getpid(39): 获取调用进程的进程 ID (PID)。getppid(110): 获取调用进程的父进程 ID (PPID)。getuid(102): 获取真实用户 ID。geteuid(107): 获取有效用户 ID。getgid(104): 获取真实组 ID。getegid(108): 获取有效组 ID。setuid(105): 设置用户 ID。setgid(106): 设置组 ID。getgroups(115): 获取附加组 ID 列表。setgroups(116): 设置附加组 ID 列表。setreuid(113): 设置真实和有效用户 ID。setregid(114): 设置真实和有效组 ID。setresuid(117): 设置真实、有效和保存的用户 ID。setresgid(119): 设置真实、有效和保存的组 ID。getresuid(118): 获取真实、有效和保存的用户 ID。getresgid(120): 获取真实、有效和保存的组 ID。setsid(112): 创建新的会话。getsid(124): 获取会话 ID。setpgid(109): 设置进程组 ID。getpgid(121): 获取进程组 ID。getpgrp(111): 获取当前进程的进程组 ID。prctl(157): 操作进程属性(如设置进程名、安全模块等)。arch_prctl(158): 特定于架构的进程控制(x86_64 上用于设置 FS/GS 段基址)。personality(135): 设置进程执行域(personality)。getpriority(140): 获取进程/进程组的调度优先级。setpriority(141): 设置进程/进程组的调度优先级。sched_setscheduler(144): 设置进程的调度策略和参数。sched_getscheduler(145): 获取进程的调度策略。sched_yield(24): 主动让出 CPU。sched_get_priority_max(146): 获取指定调度策略的最大优先级。sched_get_priority_min(147): 获取指定调度策略的最小优先级。sched_rr_get_interval(148): 获取 SCHED_RR 策略的时间片。nanosleep(35): 高精度睡眠。getitimer(36): 获取间隔计时器值。setitimer(38): 设置间隔计时器值。
文件 I/O (File Input/Output)
open(2): 打开或创建文件。openat(257): 类似open,但允许指定相对路径的基准目录描述符。creat(85): 创建新文件(等同于open带O_CREAT|O_WRONLY|O_TRUNC标志)。close(3): 关闭打开的文件描述符。read(0): 从文件描述符读取数据。write(1): 向文件描述符写入数据。pread64(17): 从文件指定偏移量读取数据(原子操作)。pwrite64(18): 向文件指定偏移量写入数据(原子操作)。readv(19): 从文件描述符读取数据到多个缓冲区(分散读)。writev(20): 从多个缓冲区写入数据到文件描述符(集中写)。lseek(8): 设置文件偏移量。fcntl(72): 对打开的文件描述符进行各种控制操作(如复制描述符、设置标志)。dup(32): 复制文件描述符。dup2(33): 复制文件描述符,并允许指定新的描述符号。dup3(292): 类似dup2,但允许设置O_CLOEXEC标志。select(23): I/O 多路复用,监视多个文件描述符。poll(7): I/O 多路复用,监视多个文件描述符。epoll_create(213): 创建 epoll 实例。epoll_create1(291): 创建 epoll 实例,允许设置标志。epoll_ctl(233): 控制 epoll 实例(添加/修改/删除监视的文件描述符)。epoll_wait(232): 等待 epoll 实例上的事件。pipe(22): 创建管道。pipe2(293): 创建管道,允许设置标志(如O_CLOEXEC,O_NONBLOCK)。
文件系统控制 (File System Control)
stat(4): 获取文件状态信息。lstat(6): 获取文件状态信息(不跟随符号链接)。fstat(5): 获取打开文件描述符对应的文件状态信息。newstat(106, 64-bit 版本): 获取文件状态信息(64位兼容)。newlstat(107, 64-bit 版本): 获取文件状态信息(不跟随符号链接,64位兼容)。newfstat(108, 64-bit 版本): 获取打开文件描述符对应的文件状态信息(64位兼容)。statfs(137): 获取文件系统统计信息。fstatfs(138): 获取打开文件描述符所在文件系统的统计信息。access(21): 检查调用进程是否可以访问文件(按实际用户ID和组ID)。chmod(90): 改变文件权限。fchmod(91): 改变打开文件描述符对应的文件权限。chown(92): 改变文件所有者和组。fchown(93): 改变打开文件描述符对应的文件所有者和组。lchown(94): 改变符号链接本身的所有者和组。truncate(76): 将文件截断或扩展到指定长度。ftruncate(77): 将打开文件描述符对应的文件截断或扩展到指定长度。utime(132): 改变文件的访问时间和修改时间。utimes(235): 改变文件的访问时间和修改时间(使用timeval结构)。link(86): 创建硬链接。linkat(265): 创建硬链接,允许指定相对路径基准。symlink(88): 创建符号链接。symlinkat(266): 创建符号链接,允许指定相对路径基准。readlink(89): 读取符号链接的内容。readlinkat(267): 读取符号链接的内容,允许指定相对路径基准。unlink(87): 删除目录项(通常用于删除文件)。unlinkat(263): 删除目录项,允许指定相对路径基准和标志。rename(82): 重命名文件或目录。renameat(264): 重命名文件或目录,允许指定相对路径基准。mkdir(83): 创建目录。mkdirat(258): 创建目录,允许指定相对路径基准。rmdir(84): 删除空目录。chdir(80): 改变当前工作目录。fchdir(81): 通过文件描述符改变当前工作目录。getcwd(79): 获取当前工作目录路径。umask(95): 设置或获取文件模式创建掩码。mknod(133): 创建特殊文件(设备文件、FIFO)。mknodat(259): 创建特殊文件,允许指定相对路径基准。getdents(78): 读取目录内容(旧接口)。getdents64(217): 读取目录内容(新接口,支持 64 位 inode)。
内存管理 (Memory Management)
brk(12): 改变数据段大小。sbrk(12, 库函数封装): 改变数据段大小。mmap(9): 将文件或设备映射到内存,或分配匿名内存。munmap(11): 解除内存映射。mremap(25): 重新映射虚拟内存地址。msync(26): 将映射区域的修改同步到文件。mprotect(10): 设置内存页的保护属性。mincore(27): 确定内存页是否在物理内存中。madvise(28): 给内核提供关于内存访问模式的建议。shmget(29): 分配 System V 共享内存段。shmat(30): 连接 System V 共享内存段。shmdt(67): 断开 System V 共享内存段连接。shmctl(31): 控制 System V 共享内存段。
信号处理 (Signal Handling)
signal(48, 库函数封装): 设置信号处理函数(不推荐直接使用,推荐sigaction)。sigaction(13): 检查或修改信号的处理动作。sigprocmask(14): 检查或修改信号掩码。sigpending(15): 检查挂起的信号。sigsuspend(16): 等待信号。sigaltstack(131): 设置或获取信号栈信息。
时间管理 (Time Management)
time(201): 获取当前时间(秒)。gettimeofday(96): 获取当前时间(秒和微秒)。settimeofday(164): 设置系统时间。clock_gettime(228): 获取指定时钟的时间。clock_settime(227): 设置指定时钟的时间。clock_getres(229): 获取指定时钟的精度。
套接字 (Sockets)
socket(41): 创建套接字。bind(49): 将套接字绑定到地址。connect(42): 建立到另一个套接字的连接。listen(50): 监听套接字上的连接。accept(43): 接受一个套接字连接。getsockname(51): 获取套接字本地地址。getpeername(52): 获取套接字对端地址。socketpair(53): 创建一对已连接的套接字。send(44): 通过套接字发送消息。recv(45): 通过套接字接收消息。sendto(46): 通过套接字发送数据报。recvfrom(47): 通过套接字接收数据报。shutdown(48): 关闭套接字的全部或部分连接。setsockopt(54): 设置套接字选项。getsockopt(55): 获取套接字选项。sendmsg(46): 通过套接字发送消息(支持辅助数据)。recvmsg(47): 通过套接字接收消息(支持辅助数据)。
用户和组管理 (User and Group Management)
- (已在进程控制部分列出:
getuid,geteuid,getgid,getegid,setuid,setgid,getgroups,setgroups,setreuid,setregid,setresuid,setresgid,getresuid,getresgid)
- (已在进程控制部分列出:
系统信息和控制 (System Information and Control)
uname(63): 获取系统名称、版本等信息。sysinfo(179): 获取系统统计信息。times(100): 获取进程时间。getrusage(98): 获取资源使用信息。syslog(103): 读写内核日志缓冲区。iopl(172): 设置 I/O 权限级别(需要特权)。ioperm(173): 设置端口 I/O 权限位图(需要特权)。
其他 (Miscellaneous)
ioctl(16): 设备特定的 I/O 操作。fcntl(72): 文件描述符控制(已在文件 I/O 部分列出)。mount(165): 挂载文件系统。umount2(166): 卸载文件系统。pivot_root(155): 改变根文件系统。swapon(167): 启用交换空间。swapoff(168): 禁用交换空间。reboot(169): 重启或关闭系统(需要特权)。init_module(171): 加载内核模块(需要特权)。delete_module(176): 卸载内核模块(需要特权)。kexec_load(246): 加载新的内核以供kexec使用。acct(163): 启用或禁用进程记账。capget(125): 获取线程的能力。capset(126): 设置线程的能力。ptrace(101): 进程跟踪。sysfs(139): 获取关于系统文件系统的信息。ustat(136): 获取文件系统统计信息(已废弃)。
Linux 5.x 内核系统调用 (基于 x86_64 架构)
Linux 5.x 是一个较新的内核系列,它在保持向后兼容的同时,引入了许多新特性和系统调用。
系统调用分类与接口 (与 3.0 相比的主要变化)
核心分类基本一致,但在具体调用上有所增减和演进:
新增的系统调用 (New Syscalls):
io_uring_setup(425): 设置 io_uring 异步 I/O 接口。io_uring_enter(426): 启动/提交 io_uring 操作。io_uring_register(427): 注册文件/缓冲区等供 io_uring 使用。openat2(437):openat的扩展版本,提供更多控制选项。pidfd_send_signal(424): 通过 PID 文件描述符发送信号,更安全。pidfd_open(434): 为进程 ID 打开一个文件描述符。clone3(435):clone的扩展版本,提供更丰富的参数。close_range(436): 关闭一个范围内的文件描述符。fsconfig(431): 配置和管理文件系统挂载参数。fsmount(432): 创建挂载实例。fsopen(430): 打开文件系统。fspick(433): 选择文件系统挂载点。move_mount(429): 移动挂载点。open_tree(428): 打开目录树以进行挂载操作。landlock_create_ruleset(444+): Landlock LSM 安全模块相关。landlock_add_rule(445+): Landlock LSM 安全模块相关。landlock_restrict_self(446+): Landlock LSM 安全模块相关。memfd_secret(447+): 创建一个内存文件描述符,其内容对内核其他部分保密。process_mrelease(448+): 释放与进程相关的内存。futex_waitv(449+):futex的扩展,支持等待多个 futex。set_mempolicy_home_node(450+): 设置内存策略的首选 NUMA 节点。
演进和改进 (Evolution & Improvements):
statx(332): 一个新的、更强大和灵活的获取文件状态信息的系统调用,旨在替代stat/lstat/fstat系列。它提供了更丰富的元数据和更好的性能。copy_file_range(326): 在两个文件描述符之间高效地复制数据,内核层面优化。preadv2(327),pwritev2(328):preadv/pwritev的增强版,支持额外的标志(如RWF_NOWAIT,RWF_HIPRI)。pkey_mprotect(329): 与内存保护密钥(Memory Protection Keys)一起使用,提供比mprotect更细粒度的保护。pkey_alloc(330),pkey_free(331): 分配和释放内存保护密钥。statfs/fstatfs行为改进: 对某些文件系统的支持和信息返回可能更完善。mount/umount相关: 旧的mount系统调用仍然存在,但新的文件系统 API (fsopen,fsconfig,fsmount等) 提供了更现代、更安全的挂载方式。seccomp增强: 与安全相关的系统调用可能有更新,用于构建更严格的沙箱。
废弃或不推荐 (Deprecated/Obsolete):
- 一些旧的、功能重叠或有安全问题的调用可能被标记为废弃,鼓励使用新接口。例如,某些特定架构的旧调用可能不再推荐。
sysfs(139): 在某些场景下可能被新的接口替代或使用减少。
核心功能保持稳定 (Core Functionality Remains Stable):
read,write,open,close,fork,execve,mmap,socket,bind,connect等基础且核心的系统调用在 5.x 中依然存在,保证了向后兼容性。它们的编号和基本语义通常不变。
总结
- Linux 3.0: 代表了内核成熟期的一个稳定版本,包含了当时绝大多数常用和必要的系统调用。其分类清晰,是学习经典 Linux 系统编程的良好起点。
- Linux 5.x: 在 3.0 的基础上,增加了许多现代化特性,特别是在异步 I/O (
io_uring)、安全 (Landlock,memfd_secret)、内存管理 (pkey_*)、文件系统操作 (新挂载 API) 和进程控制 (clone3,pidfd_*) 方面。这些新调用旨在提高性能、安全性、灵活性和易用性。
学习建议:
- 从基础开始: 先掌握 3.0 中列出的核心系统调用,理解它们的工作原理和使用场景。
- 查阅手册: 始终使用
man 2 syscall_name来获取最准确的文档。 - 实践编码: 通过编写小程序来实践这些调用。
- 关注演进: 学习 5.x 新增的调用,特别是那些能显著提升性能或安全性的功能(如
io_uring,statx)。 - 检查兼容性: 如果你的程序需要在不同内核版本上运行,务必检查所使用的系统调用的可用性。
希望这份详细的分类和介绍能帮助你更好地理解 Linux 系统编程!