全世界 99% 的服务器、路由器、交换机、嵌入式设备、数据库、操作系统,全部都是用 C 语言写的,而且全部跑在 Linux 系统上。掌握 Linux 系统编程,才能真正发挥 C 语言的威力。一、为什么要学 Linux 系统编程?
就业面最广:后端开发、嵌入式开发、运维开发、内核开发、网络安全,所有岗位都要求掌握 Linux 系统编程
薪资最高:C 语言相关岗位的平均薪资比 Java、前端高 20% 以上,资深 Linux 开发工程师年薪轻松过 50 万
最有技术壁垒:Linux 系统编程是所有计算机技术的基石,学会了再学其他语言和框架都是降维打击
永远不会过时:Linux 内核已经稳定运行了 30 多年,未来 30 年也不会被淘汰
二、什么是系统调用?
Linux 系统分为两层:用户态和内核态。平时写的普通程序都运行在用户态,不能直接访问硬件和操作系统内核资源。如果想要访问硬件、读写文件、创建进程,就必须通过系统调用向内核发起请求。简单来说:系统调用就是操作系统提供给用户程序的 API。之前用的 printf、fopen、malloc 等标准库函数,底层都是封装了系统调用。标准库函数 vs 系统调用
在高性能场景下,会直接使用系统调用,绕过标准库的缓冲区。三、Linux 开发环境准备
所有 Linux 系统编程的代码都必须在 Linux 环境下运行。推荐三种方式:WSL2(Windows 用户):Windows 10/11 自带的 Linux 子系统,安装简单,性能好
云服务器:阿里云、腾讯云的轻量应用服务器,一年几十块钱
虚拟机:VMware + Ubuntu 22.04 LTS
安装好 Linux 后,只需要一个 gcc 编译器和一个文本编辑器即可:四、第一个 Linux 系统调用程序
不用 printf,直接用write系统调用向屏幕输出 "Hello Linux!"。这就是一个完整的 Linux 系统调用程序,没有包含 stdio.h,没有用 printf,直接和内核交互。五、文件 I/O 系统调用(企业级标准写法)
Linux 中一切皆文件,所有设备(硬盘、键盘、鼠标、网络)都被抽象成文件,我们可以用统一的四个系统调用来操作所有文件:open:打开文件
read:读取文件
write:写入文件
close:关闭文件
1. open:打开文件
pathname:文件路径
flags:打开方式
mode:文件权限,只有创建文件时需要
返回值:成功返回文件描述符(一个非负整数),失败返回 - 1
2. read:读取文件
fd:open 返回的文件描述符
buf:存放读取数据的缓冲区
count:要读取的字节数
返回值:成功返回实际读取的字节数,到达文件末尾返回 0,失败返回 - 1
3. write:写入文件
参数和 read 类似,返回值是实际写入的字节数
4. close:关闭文件
关闭文件描述符,释放资源
程序退出时系统会自动关闭所有打开的文件,但良好的习惯是手动关闭
六、实战:用系统调用实现高性能文件复制
用这四个系统调用实现一个文件复制程序,比用标准库 fread/fwrite 快 。直接使用系统调用,绕过标准库的缓冲区
使用 4KB 缓冲区,正好是 Linux 系统的页大小,磁盘 I/O 效率最高
没有多余的格式转换,直接读写二进制数据
七、错误处理:perror 函数
系统调用失败时会设置全局变量errno,我们可以用perror函数打印出对应的错误信息:这是 Linux 系统编程中标准的错误处理方式,一定要养成每次系统调用都检查返回值的习惯。八、总结
用户态和内核态:程序运行在用户态,通过系统调用访问内核
系统调用:操作系统提供的 API,直接和内核交互
文件描述符:Linux 中所有资源的抽象
四个基本文件 I/O 系统调用:open、read、write、close
这些是所有 Linux 系统编程的基础,后面我们要学的进程、线程、网络编程,全部都是建立在这些基础之上的。大家有任何不懂的地方,或者敲代码遇到了 bug,都可以在评论区留言,我都会一一回复。如果这篇内容对你有帮助,别忘了点赞、在看、转发给身边同样在学 C 语言的朋友。