EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
所谓系统调用是指操作系统提供给用户程序调用的一组“特殊”接口,用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务。例如用户可以通过进程控制相关的系统调用来创建进程、实现进程调度、进程管理等。
4 N) k2 e1 ~; q( x在这里,为什么用户程序不能直接访问系统内核提供的服务呢?这是由于在 Linux 中,为了更好地保护内核空间,将程序的运行空间分为内核空间和用户空间(也就是常称的内核态和用户态),它们分别运行在不同的级别上,在逻辑上是相互隔离的。因此,用户进程在通常情况下不允许访问内核数据,也无法使用内核函数,它们只能在用户空间操作用户数据,调用用户空间的函数。 但是,在有些情况下,用户空间的进程需要获得一定的系统服务(调用内核空间程序),这时操作系统就必须利用系统提供给用户的“特殊接口”——系统调用规定用户进程进入内核空间的具体位置。进行系统调用时,程序运行空间需要从用户空间进入内核空间,处理完后再返回到用户空间。
/ {, Y" ~& Z2 A% x3 i5 iLinux 系统调用部分是非常精简的系统调用(只有 250 个左右),它继承了 UNIX 系统调用中最基本和最有用的部分。这些系统调用按照功能逻辑大致可分为进程控制、进程间通信、文件系统控制、系统控制、存储管理、网络管理、socket 控制、用户管理等几类。
在 Linux 中对目录和设备的操作都等同于文件的操作,因此,大大简化了系统对不同设备的处理,提高了效率。Linux 中的文件主要分为 4 种:普通文件、目录文件、链接文件和设备文件。 那么,内核如何区分和引用特定的文件呢?这里用到的就是一个重要的概念——文件描述符。对于 Linux 而言,所有对设备和文件的操作都使用文件描述符来进行的。文件描述符是一个非负的整数,它是一个索引值,并指向内核中每个进程打开文件的记录表。当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数。 通常,一个进程启动时,都会打开 3 个文件:标准输入、标准输出和标准出错处理。这3 个文件分别对应文件描述符为 0、1 和 2(也就是宏替换 STDIN_FILENO、STDOUT_FILENO和 STDERR_FILENO,鼓励读者使用这些宏替换)。 基于文件描述符的 I/O 操作虽然不能移植到类 Linux 以外的系统上去(如 Windows),但它往往是实现某些 I/O 操作的惟一途径,如 Linux 中低级文件操作函数、多路 I/O、TCP/IP 套接字编程接口等。同时,它们也很好地兼容 POSIX 标准,因此,可以很方便地移植到任何 POSIX 平台上。基于文件描述符的 I/O 操作是 Linux 中最常用的操作之一。 以下列出了大部分常见的Linux系统调用,并附有简要中文说明。这儿没有列出详细的函数接口,可以使用man 2 syscalls 来查看相关的帮助文档。 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数。这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的。 按照惯例,这个列表以man pages第2节,即系统调用节为蓝本。按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统调用,对个别本人稍觉不妥的地方作了一些小的修改,并对所有列出的系统调用附上简要注释。 其中有一些函数的作用完全相同,只是参数不同。(可能很多熟悉C++朋友马上就能联想起函数重载,但是别忘了Linux核心是用C语言写的,所以只能取成不同的函数名)。还有一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数我会在前面标上“*”号以示区别。 一、进程控制: fork | 创建一个新进程 | clone | 按指定条件创建子进程 | execve | 运行可执行文件 | exit | 中止进程 | _exit | 立即中止当前进程 | getdtablesize | 进程所能打开的最大文件数 | getpgid | 获取指定进程组标识号 | setpgid | 设置指定进程组标志号 | getpgrp | 获取当前进程组标识号 | setpgrp | 设置当前进程组标志号 | getpid | 获取进程标识号 | getppid | 获取父进程标识号 | getpriority | 获取调度优先级 | setpriority | 设置调度优先级 | modify_ldt | 读写进程的本地描述表 | nanosleep | 使进程睡眠指定的时间 | nice | 改变分时进程的优先级 | pause | 挂起进程,等待信号 | personality | 设置进程运行域 | prctl | 对进程进行特定操作 | ptrace | 进程跟踪 | sched_get_priority_max | 取得静态优先级的上限 | sched_get_priority_min | 取得静态优先级的下限 | sched_getparam | 取得进程的调度参数 | sched_getscheduler | 取得指定进程的调度策略 | sched_rr_get_interval | 取得按RR算法调度的实时进程的时间片长度 | sched_setparam | 设置进程的调度参数 | sched_setscheduler | 设置指定进程的调度策略和参数 | sched_yield | 进程主动让出处理器,并将自己等候调度队列队尾 | vfork | 创建一个子进程,以供执行新程序,常与execve等同时使用 | wait | 等待子进程终止 | wait3 | 参见wait | waitpid | 等待指定子进程终止 | wait4 | 参见waitpid | capget | 获取进程权限 | capset | 设置进程权限 | getsid | 获取会晤标识号 | setsid | 设置会晤标识号 |
' d3 t f+ m N- X' J5 w! C" ~0 C* ~: j6 r& }/ h- v5 t7 `
b3 C$ `1 b- [: A5 A! v二、文件系统控制
3 o& w9 F7 o: l; r1 ?8 D1、文件读写操作
fcntl | 文件控制 | open | 打开文件 | creat | 创建新文件 | close | 关闭文件描述字 | read | 读文件 | write | 写文件 | readv | 从文件读入数据到缓冲数组中 | writev | 将缓冲数组里的数据写入文件 | pread | 对文件随机读 | pwrite | 对文件随机写 | lseek | 移动文件指针 | _llseek | 在64位地址空间里移动文件指针 | dup | 复制已打开的文件描述字 | dup2 | 按指定条件复制文件描述字 | flock | 文件加/解锁 | poll | I/O多路转换 | truncate | 截断文件 | ftruncate | 参见truncate | umask | 设置文件权限掩码 | fsync | 把文件在内存中的部分写回磁盘 |
6 C8 J: n5 ~7 U) `* a
" \* m$ ^2 H- |& c c3 C; V1 {8 L2、文件系统操作 access | 确定文件的可存取性 | chdir | 改变当前工作目录 | fchdir | 参见chdir | chmod | 改变文件方式 | fchmod | 参见chmod | chown | 改变文件的属主或用户组 | fchown | 参见chown | lchown | 参见chown | chroot | 改变根目录 | stat | 取文件状态信息 | lstat | 参见stat | fstat | 参见stat | statfs | 取文件系统信息 | fstatfs | 参见statfs | readdir | 读取目录项 | getdents | 读取目录项 | mkdir | 创建目录 | mknod | 创建索引节点 | rmdir | 删除目录 | rename | 文件改名 | link | 创建链接 | symlink | 创建符号链接 | unlink | 删除链接 | readlink | 读符号链接的值 | mount | 安装文件系统 | umount | 卸下文件系统 | ustat | 取文件系统信息 | utime | 改变文件的访问修改时间 | utimes | 参见utime | quotactl | 控制磁盘配额 |
: |: b7 ^, ^8 `; V: s# n( U# Q& b% t0 y% V( Z% z8 \% Y+ A
8 @& e3 ]5 g/ m5 N三、系统控制 ioctl | I/O总控制函数 | _sysctl | 读/写系统参数 | acct | 启用或禁止进程记账 | getrlimit | 获取系统资源上限 | setrlimit | 设置系统资源上限 | getrusage | 获取系统资源使用情况 | uselib | 选择要使用的二进制函数库 | ioperm | 设置端口I/O权限 | iopl | 改变进程I/O权限级别 | outb | 低级端口操作 | reboot | 重新启动 | swapon | 打开交换文件和设备 | swapoff | 关闭交换文件和设备 | bdflush | 控制bdflush守护进程 | sysfs | 取核心支持的文件系统类型 | sysinfo | 取得系统信息 | adjtimex | 调整系统时钟 | alARM | 设置进程的闹钟 | getitimer | 获取计时器值 | setitimer | 设置计时器值 | gettimeofday | 取时间和时区 | settimeofday | 设置时间和时区 | stime | 设置系统日期和时间 | time | 取得系统时间 | times | 取进程运行时间 | uname | 获取当前UNIX系统的名称、版本和主机等信息 | vhangup | 挂起当前终端 | nfsservctl | 对NFS守护进程进行控制 | vm86 | 进入模拟8086模式 | create_module | 创建可装载的模块项 | delete_module | 删除可装载的模块项 | init_module | 初始化模块 | query_module | 查询模块信息 | *get_kernel_syms | 取得核心符号,已被query_module代替 | ) ^% u" o0 \+ y N( l# z
$ M) `' a1 ~+ e四、内存管理 brk | 改变数据段空间的分配 | sbrk | 参见brk | mlock | 内存页面加锁 | munlock | 内存页面解锁 | mlockall | 调用进程所有内存页面加锁 | munlockall | 调用进程所有内存页面解锁 | mmap | 映射虚拟内存页 | munmap | 去除内存页映射 | mremap | 重新映射虚拟内存地址 | msync | 将映射内存中的数据写回磁盘 | mprotect | 设置内存映像保护 | getpagesize | 获取页面大小 | sync | 将内存缓冲区数据写回硬盘 | cacheflush | 将指定缓冲区中的内容写回磁盘 | 3 t$ m5 v& j U" M6 {' y
. [! [* O" f& \) e7 H# s
5 T* l4 g# m6 e5 J/ T五、网络管理
4 F4 z2 T' j6 j8 R* P# L3 I
getdomainname | 取域名 | setdomainname | 设置域名 | gethostid | 获取主机标识号 | sethostid | 设置主机标识号 | gethostname | 获取本主机名称 | sethostname | 设置主机名称 |
! r" M! A/ t) y" ` V5 R3 M3 k# s; T
4 M& h+ L$ K. L# B. ~( Y六、socket控制 socketcall | socket系统调用 | socket | 建立socket | bind | 绑定socket到端口 | connect | 连接远程主机 | accept | 响应socket连接请求 | send | 通过socket发送信息 | sendto | 发送UDP信息 | sendmsg | 参见send | recv | 通过socket接收信息 | recvfrom | 接收UDP信息 | recvmsg | 参见recv | listen | 监听socket端口 | select | 对多路同步I/O进行轮询 | shutdown | 关闭socket上的连接 | getsockname | 取得本地socket名字 | getpeername | 获取通信对方的socket名字 | getsockopt | 取端口设置 | setsockopt | 设置端口参数 | sendfile | 在文件或端口间传输数据 | socketpair | 创建一对已联接的无名socket |
/ k; U0 j8 T# d* {, N! c
8 _' s4 Z- t v3 @, _; u: }) a. w" s5 |
七、用户管理 getuid | 获取用户标识号 | setuid | 设置用户标志号 | getgid | 获取组标识号 | setgid | 设置组标志号 | getegid | 获取有效组标识号 | setegid | 设置有效组标识号 | geteuid | 获取有效用户标识号 | seteuid | 设置有效用户标识号 | setregid | 分别设置真实和有效的的组标识号 | setreuid | 分别设置真实和有效的用户标识号 | getresgid | 分别获取真实的,有效的和保存过的组标识号 | setresgid | 分别设置真实的,有效的和保存过的组标识号 | getresuid | 分别获取真实的,有效的和保存过的用户标识号 | setresuid | 分别设置真实的,有效的和保存过的用户标识号 | setfsgid | 设置文件系统检查时使用的组标识号 | setfsuid | 设置文件系统检查时使用的用户标识号 | getgroups | 获取后补组标志清单 | setgroups | 设置后补组标志清单 |
% ?: R# J' p- r) I, w1 q& o4 u* a! ~" b
八、进程间通信 6 f5 N. w! P2 O' H" C1 u6 L' \8 ~3 }9 _
! y9 X! U8 k3 S! D
1、信号 sigaction | 设置对指定信号的处理方法 | sigprocmask | 根据参数对信号集中的信号执行阻塞/解除阻塞等操作 | sigpending | 为指定的被阻塞信号设置队列 | sigsuspend | 挂起进程等待特定信号 | signal | 参见signal | kill | 向进程或进程组发信号 | *sigblock | 向被阻塞信号掩码中添加信号,已被sigprocmask代替 | *siggetmask | 取得现有阻塞信号掩码,已被sigprocmask代替 | *sigsetmask | 用给定信号掩码替换现有阻塞信号掩码,已被sigprocmask代替 | *sigmask | 将给定的信号转化为掩码,已被sigprocmask代替 | *sigpause | 作用同sigsuspend,已被sigsuspend代替 | sigvec | 为兼容BSD而设的信号处理函数,作用类似sigaction | ssetmask | ANSI C的信号处理函数,作用类似sigaction | - @; Q; d% @) G' K1 [3 I: b
+ b6 S/ `# [; q" V
2、消息 msgctl | 消息控制操作 | msgget | 获取消息队列 | msgsnd | 发消息 | msgrcv | 取消息 |
. O& j. ]5 r) l" v2 P
2 O4 q3 U( i! P9 Z: |3、管道 , C# |2 y9 _1 Z6 R) }6 l- b/ U
|. W) `* n: p+ \! d/ N8 S4、信号量 sEMCtl | 信号量控制 | semget | 获取一组信号量 | semop | 信号量操作 | $ t: H4 K) ]9 i8 M
6 ^2 j" Y) L7 `$ h' x2 }2 b! o5、共享内存 shmctl | 控制共享内存 | shmget | 获取共享内存 | shmat | 连接共享内存 | shmdt | 拆卸共享内存 |
* j- i' P' y/ C. J5 X
3 ~. o' u8 P$ ^7 n) ^# Q, O参考资料 - Linux man pages
- Advanced Programming in the UNIX Environment, W. Richard Stevens, 1993
- `! ?! K! S4 G" M) S g+ H6 D, d
5 G' M: [7 \* ?+ N* W! H, r
( c8 k; [" D0 b4 Z* q9 ?
' j/ p7 y+ k5 ] F! v( ^& B# e6 g0 C! t" B
|