基本信息
编辑推荐
Linux系统编程经典之作,根据Linux内核3.0更新
内容简介
计算机书籍
系统编程是指编写系统软件,其代码在底层运行,直接跟内核和核心系统库对话。
《Linux系统编程(第2版)》是一本关于Linux系统编程的教程,也是一本介绍Linux系统调用的手册,还是一本如何实现更优雅更快代码的内幕指南。全书分为11章和2个附录,详细介绍了Linux系统编程基本概念、文件I/O、缓冲I/O、高级文件I/O、进程管理、高级进程管理、线程、文件和目录管理、信号和时间等主题。附录给出了gcc和GNU C提供的很多语言扩展,以及推荐阅读的相关书目。
《Linux系统编程(第2版)》的作者是知名的Linux内核专家,多本畅销技术图书的作者。本书需要在C编程和Linux编程环境下工作的程序员阅读,对于想要巩固基础或了解内核的高级编程人员,本书也很有参考价值。
作译者
目录
第1章 入门和基本概念 1
1.1 系统编程 1
1.1.1 为什么要学习系统编程 2
1.1.2 系统编程的基础 2
1.1.3 系统调用 3
1.1.4 C库 3
1.1.5 C编译器 4
1.2 API和ABI 4
1.2.1 API 5
1.2.2 ABI 5
1.3 标准 6
1.3.1 POSIX和SUS的历史 6
1.3.2 C语言标准 7
1.3.3 Linux和标准 8
1.3.4 本书和标准 8
1.4 Linux编程的概念 9
1.4.1 文件和文件系统 9
1.4.2 进程 15
1.4.3 用户和组 16
前言
虽然已经有很多书探讨UNIX上的系统编程,却很少有专注于探讨Linux方面的书籍,而探讨最新版本的Linux以及Linux特有的高级接口的书籍更是凤毛麟角。此外,本书还有一个优势:我为Linux贡献了很多代码,包括内核及其上面的系统软件。实际上,本书中提到的一些系统调用和系统软件就是我实现的。因此,本书涉及很多内幕资料,不仅介绍系统接口如何工作,还阐述它们实际上是如何工作,以及如何高效利用这些接口。因此,本书既是一本关于Linux系统编程的教程,也是一本介绍Linux系统调用的手册,同时还是一本如何实现更优雅、更快代码的内幕指南。这本书内容翔实,不管你是否每天都在编写系统级代码,本书给出的很多技巧都有助于你成为更优秀的软件工程师。
目标读者和假设
本书假定读者熟悉C编程和Linux编程环境——不要求很精通,但至少比较熟悉。如果你不习惯于UNIX文本编辑器——Emacs和vim(后者成为最广泛使用的编辑器,而且评价很高),那么至少应该熟悉一个。你还应该对如何使用gcc、gdb、make等工具很熟悉。已经有很多书籍介绍了关于Linux编程的工具和实践,本书最后的附录B给出一些有用的资源。
我并没有假设用户了解UNIX或Linux系统编程。本书是从零开始,从最基本的开始介绍,一直到高级接口和一些优化技巧。我希望不同层次的读者都能够从本书学到一些新东西,觉得本书有价值。在写本书过程中,我自己就感觉颇有收获。
同样,我并不想去说服或鼓励读者做什么。目标读者显然是那些希望能够(更好地)在系统上编程的工程师,但是希望奠定更坚实的基础的高级编程人员还可以找到很多其他有趣的资料。本书也适合那些只是出于好奇的黑客,它应该能够满足他们的好奇心。本书目标是希望能够满足大部分的编程人员。
不管出于什么目的,最重要的是,希望你会觉得本书很有意思。
本书的内容
本书共包含11章和2个附录。
第1章,入门和基本概念
本章是入门介绍,简要介绍了Linux、系统编程、内核、C库和C编译器。即使是高级用户也应该看看本章内容。
第2章,文件I/O
本章介绍文件,它是UNIX环境的最重要的抽象,介绍文件I/O,它是Linux编程模型的基础。其内容涉及读写文件以及一些其他基础的文件I/O操作。最后还探讨了Linux内核是如何实现和管理文件的。
第3章,缓冲I/O
本章探讨了基础文件I/O接口的一个方面:缓存大小管理,它从解决方案角度探讨了缓冲I/O和标准I/O。
第4章,高级文件I/O
本章阐述了高级I/O接口、存储映射和优化机制。它探讨了如何避免查找的很多技巧,并介绍了Linux内核I/O调度器。
第5章,进程管理
本章介绍了UNIX第二大重要抽象:进程,以及与基础进程管理相关的一系列系统调用,包括“久经风霜”的fork调用。
第6章,高级进程管理
媒体评论
——Jeremy Allison,Samba Team
书摘
正如前面所提到的那样,一个进程已经终止了,但是它的父进程还没有获取到其状态,那么这个进程就叫做僵尸进程。僵尸进程还会消耗一些系统资源,虽然消耗很少——仅仅够描述进程之前状态的一些概要信息。保留这些概要信息主要是为了在父进程查询子进程的状态时可以提供相应的信息。一旦父进程得到了想要的信息,内核就会清除这些信息,僵尸进程就不存在了。
然而任何用过UNIX系统的人都会或多或少地看到过僵尸进程。通常称这些进程为“幽灵进程(ghosts)”,这些进程没有相应的父进程。如果进程创建了一个子进程,那么它就有责任去等待子进程(除非它的生命周期很短,这种情况你很快就会看到),即使会丢弃得到的子进程信息。否则,如果父进程没有等待子进程,其所有子进程就会成为幽灵进程,并一直存在,占满系统的进程列表,导致应用非常慢,让人讨厌。
然而,如果父进程在子进程结束之前就结束了呢?或者父进程还没有机会等待其僵尸的子进程,就先结束了呢?无论何时,只要有进程结束了,内核就会遍历它的所有子进程,并且把它们的父进程重新设为init进程(即pid为1的那个进程)。这保证了系统中不存在没有父进程的进程。init进程会周期性地等待所有子进程,确保不会有长时间存在的僵尸进程——没有幽灵进程!因此,当父进程在子进程之前结束,或者在退出前没有等待子进程,那么init进程会被指定为这些子进程的父进程,从而确保了它们最终会退出。这种处理方式受到人们的推崇,不过这种安全措施也意味着生命周期短的进程没有必要等待它所有的子进程结束。
5.6用户和组
正如本章前面和第l章中所讨论过的,进程是与用户和组相关联的。用户ID和组ID分别用C语言的uid—t和gid_t这两个类型表示。映射表示数值和可读字符串之间的关系(例如root用户的uid是0),是通过文件/etc/passwd和/etc/group在用户空间完成的。内核只处理数值形式。