【Linux】系统调用和库函数汇总整理
Linux系统调用和库函数是操作系统和应用程序之间的重要接口。系统调用允许应用程序与内核进行交互,而库函数则为开发者提供了更高层次的抽象和更友好的接口。下面是对Linux系统调用和库函数的详细汇总整理。
系统调用
系统调用是操作系统提供的一组接口,允许用户空间的应用程序请求内核执行特定的任务。系统调用通常涉及内核态和用户态之间的上下文切换。
文件操作
-
open():
int open(const char *pathname, int flags[, ...])
: 打开或创建文件。- 参数
pathname
指定文件路径,flags
指定打开模式。
-
close():
int close(int filedes)
: 关闭文件描述符。- 参数
filedes
是文件描述符。
-
read():
ssize_t read(int filedes, void *buf, size_t nbyte)
: 从文件描述符读取数据。- 参数
filedes
是文件描述符,buf
是缓冲区指针,nbyte
是要读取的字节数。
-
write():
ssize_t write(int filedes, const void *buf, size_t nbyte)
: 向文件描述符写入数据。- 参数
filedes
是文件描述符,buf
是缓冲区指针,nbyte
是要写入的字节数。
-
lseek():
off_t lseek(int filedes, off_t offset, int whence)
: 移动文件位置指示器。- 参数
filedes
是文件描述符,offset
是偏移量,whence
指定计算偏移量的基准。
-
fstat():
int fstat(int filedes, struct stat *buf)
: 获取文件的状态。- 参数
filedes
是文件描述符,buf
是存放状态信息的结构体指针。
-
fstatfs():
int fstatfs(int filedes, struct statfs *buf)
: 获取文件系统的状态。- 参数
filedes
是文件描述符,buf
是存放状态信息的结构体指针。
-
mkdir():
int mkdir(const char *pathname, mode_t mode)
: 创建目录。- 参数
pathname
指定目录路径,mode
指定权限掩码。
-
rmdir():
int rmdir(const char *pathname)
: 删除空目录。- 参数
pathname
指定目录路径。
-
rename():
int rename(const char *oldpath, const char *newpath)
: 重命名文件或目录。- 参数
oldpath
和newpath
分别指定旧路径和新路径。
-
unlink():
int unlink(const char *pathname)
: 删除文件。- 参数
pathname
指定文件路径。
进程控制
-
fork():
pid_t fork(void)
: 创建子进程。- 返回值:在父进程中返回子进程的PID,在子进程中返回0。
-
vfork():
pid_t vfork(void)
: 类似于fork()
,但在子进程中执行完_exit()
或longjmp()
前,父进程会被阻塞。- 返回值:同
fork()
。
-
execve():
int execve(const char *filename, char *const argv[], char *const envp[])
: 执行新的程序。- 参数
filename
指定程序路径,argv
是参数数组,envp
是环境变量数组。
-
wait():
pid_t wait(int *status)
: 等待任意一个子进程结束,并获取其状态。- 参数
status
可以通过宏如WIFEXITED()
、WEXITSTATUS()
等解析进程的状态。
-
waitpid():
pid_t waitpid(pid_t pid, int *status, int options)
: 等待指定的子进程结束,并获取其状态。- 参数
pid
可以指定等待哪个子进程;options
可以指定等待的行为,如WNOHANG
表示非阻塞等待。
-
exit():
void _exit(int status)
: 终止进程。- 参数
status
是退出状态。
内存管理
-
mmap():
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
: 映射文件或设备到进程的地址空间。- 参数
addr
是映射起始地址,length
是映射长度,prot
是保护标志,flags
是映射标志,fd
是文件描述符,offset
是文件偏移量。
-
munmap():
int munmap(void *addr, size_t length)
: 取消映射。- 参数
addr
是映射起始地址,length
是映射长度。
网络通信
-
socket():
int socket(int domain, int type, int protocol)
: 创建套接字。- 参数
domain
指定地址家族,type
指定套接字类型,protocol
指定协议。
-
bind():
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
: 绑定套接字到特定的地址和端口。- 参数
sockfd
是套接字描述符,addr
是指向地址结构的指针,addrlen
是地址结构的长度。
-
listen():
int listen(int sockfd, int backlog)
: 将套接字置于监听状态。- 参数
sockfd
是套接字描述符,backlog
是连接队列的最大长度。
-
accept():
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
: 接受客户端的连接请求。- 参数
sockfd
是监听套接字描述符,addr
和addrlen
用于返回客户端的地址信息。
-
connect():
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
: 连接到服务器。- 参数
sockfd
是套接字描述符,addr
和addrlen
指定服务器的地址信息。
-
send():
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
: 向套接字发送数据。- 参数
sockfd
是套接字描述符,buf
是指向数据缓冲区的指针,len
是数据长度,flags
可以指定一些选项。
-
recv():
ssize_t recv(int sockfd, void *buf, size_t len, int flags)
: 从套接字接收数据。- 参数
sockfd
是套接字描述符,buf
是指向数据缓冲区的指针,len
是数据长度,flags
可以指定一些选项。
时间和日期
-
time():
time_t time(time_t *timer)
: 获取当前时间。- 参数
timer
可以指定存放时间的变量,如果为NULL,则返回当前时间。
-
clock_gettime():
int clock_gettime(clockid_t clk_id, struct timespec *tp)
: 获取当前时间或进程时间。- 参数
clk_id
指定要获取的时间类型,tp
是存放时间信息的结构体指针。
-
nanosleep():
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
: 休眠指定的时间。- 参数
rqtp
指定要求的睡眠时间,rmtp
用于返回剩余的未完成的睡眠时间。
信号处理
-
kill():
int kill(pid_t pid, int sig)
: 发送信号给指定的进程。- 参数
pid
指定进程ID,sig
指定信号类型。
-
raise():
int raise(int sig)
: 发送信号给当前进程。- 参数
sig
指定信号类型。
-
pause():
int pause(void)
: 暂停当前进程,直到接收到信号。
-
sigaction():
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
: 设置信号处理函数和信号行为。- 参数
signum
指定信号编号,act
指定新的信号处理行为,oldact
用于返回旧的行为。
示例代码
以下是一个简单的示例,展示如何在 Linux 系统上使用 C 语言的系统调用来创建文件、写入内容、然后读取文件内容:
1#include <unistd.h>
2#include <fcntl.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7int main() {
8 int filedes;
9 char filename[] = "example.txt";
10 char buffer[] = "Hello, World!";
11 char read_buffer[1024] = {0};
12
13 // 创建或打开文件
14 filedes = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
15 if (filedes == -1) {
16 perror("无法打开文件");
17 exit(EXIT_FAILURE);
18 }
19
20 // 写入文件
21 ssize_t bytes_written = write(filedes, buffer, strlen(buffer));
22 if (bytes_written == -1) {
23 perror("无法写入文件");
24 close(filedes);
25 exit(EXIT_FAILURE);
26 }
27
28 // 移动文件位置指示器到文件开头
29 lseek(filedes, 0, SEEK_SET);
30
31 // 读取文件内容
32 ssize_t bytes_read = read(filedes, read_buffer, sizeof(read_buffer) - 1);
33 if (bytes_read == -1) {
34 perror("无法读取文件");
35 close(filedes);
36 exit(EXIT_FAILURE);
37 }
38 read_buffer[bytes_read] = '\0'; // 确保字符串以空字符结尾
39 printf("文件内容: %s\n", read_buffer);
40
41 // 关闭文件
42 if (close(filedes) == -1) {
43 perror("无法关闭文件");
44 exit(EXIT_FAILURE);
45 }
46
47 return 0;
48}
库函数
库函数是编译器提供的标准库或第三方库中封装好的函数,它们通常是对系统调用的封装,提供更高级别的抽象和更友好的接口。
文件操作
-
fopen():
FILE *fopen(const char *path, const char *mode)
: 打开文件。- 参数
path
指定文件路径,mode
指定打开模式。
-
fclose():
int fclose(FILE *stream)
: 关闭文件流。- 参数
stream
是文件流指针。
-
fread():
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream)
: 从文件读取数据。- 参数
ptr
是缓冲区指针,size
是每个元素的大小,nitems
是元素数量,stream
是文件流指针。
-
fwrite():
size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream)
: 向文件写入数据。- 参数
ptr
是缓冲区指针,size
是每个元素的大小,nitems
是元素数量,stream
是文件流指针。
-
fseek():
int fseek(FILE *stream, long offset, int whence)
: 移动文件位置指示器。- 参数
stream
是文件流指针,offset
是偏移量,whence
指定计算偏移量的基准。
-
ftell():
long ftell(FILE *stream)
: 获取当前文件位置指示器的位置。- 参数
stream
是文件流指针。
-
ferror():
int ferror(FILE *stream)
: 检查错误状态。- 参数
stream
是文件流指针。
-
feof():
int feof(FILE *stream)
: 检查是否到达文件末尾。- 参数
stream
是文件流指针。
字符串处理
-
strlen():
size_t strlen(const char *s)
: 计算字符串长度。- 参数
s
是字符串指针。
-
strcpy():
char *strcpy(char *dest, const char *src)
: 复制字符串。- 参数
dest
和src
分别是目标和源字符串指针。
-
strcat():
char *strcat(char *dest, const char *src)
: 连接字符串。- 参数
dest
和src
分别是目标和源字符串指针。
-
strcmp():
int strcmp(const char *s1, const char *s2)
: 比较字符串。- 参数
s1
和s2
是字符串指针。
-
sprintf():
size_t sprintf(char *str, const char *format, ...)
: 格式化输出到字符串。- 参数
str
是字符串指针,format
是格式字符串。
数学函数
-
sqrt():
double sqrt(double x)
: 计算平方根。- 参数
x
是双精度浮点数。
-
sin():
double sin(double x)
: 计算正弦值。- 参数
x
是双精度浮点数。
-
cos():
double cos(double x)
: 计算余弦值。- 参数
x
是双精度浮点数。
-
exp():
double exp(double x)
: 计算指数函数。- 参数
x
是双精度浮点数。
-
log():
double log(double x)
: 计算自然对数。- 参数
x
是双精度浮点数。
内存操作
-
malloc():
void *malloc(size_t size)
: 分配内存。- 参数
size
是内存大小。
-
free():
void free(void *ptr)
: 释放内存。- 参数
ptr
是内存指针。
-
memcpy():
void *memcpy(void *dest, const void *src, size_t n)
: 复制内存区域。- 参数
dest
和src
分别是目标和源指针,n
是复制的字节数。
-
memset():
void *memset(void *ptr, int value, size_t num)
: 设置内存区域的内容。- 参数
ptr
是内存指针,value
是填充值,num
是字节数。
-
realloc():
void *realloc(void *ptr, size_t size)
: 重新分配内存。- 参数
ptr
是内存指针,size
是新内存大小。
注意事项
- 在进行系统调用或库函数调用时,务必检查函数的返回值以确保操作成功。
- 使用文件后记得及时关闭,以释放系统资源。
- 对于二进制文件,应使用库函数的
"rb"
和"wb"
模式。 - 在处理大文件时,考虑使用缓冲或分块读取以提高效率。
- 跨平台编程时要注意不同操作系统之间的 API 差异。
系统调用和库函数是编程中的基础组成部分,几乎所有的应用程序都会涉及到它们的使用。理解和熟练掌握这些操作对于编写可靠、高效的程序至关重要。