万本电子书0元读

万本电子书0元读

顶部广告

LinuxUNIX系统编程手册(上、下册)电子书 租阅

  Linux/UNIX系统编程口权威巨著,无出其右;   涵盖500多个系统调用和库函数;示例清晰完整,解释巨细靡遗;   涵盖当前UNIX标准(POSI X.1-2001/SUS v3和POSI X.1-2008/SUS v4);   众多业内专家人士联袂推荐;   Linux/UNIX发人员的案头必备,注定成为新的经典;

售       价:¥

纸质售价:¥124.80购买纸书

312人正在读 | 1人评论 6.2

作       者:(德)Michael Kerrisk

出  版  社:人民邮电出版社

出版时间:2014-01-01

字       数:105.6万

所属分类: 科技 > 计算机/网络 > 软件系统

温馨提示:此类商品不支持退换货,不支持下载打印

为你推荐

  • 读书简介
  • 目录
  • 累计评论(0条)
  • 读书简介
  • 目录
  • 累计评论(0条)
  《Linux/UNIX系统编程手册(上、下册)》是介绍Linux与UNIX编程口的权威著作。Linux编程资深专家Michael Kerrisk在书中详细描述了Linux/UNIX系统编程所涉及的系统调用和库函数,并辅之以全面而清晰的代码示例。《Linux/UNIX系统编程手册(上、下册)》涵盖了逾500个系统调用及库函数,并给出逾200个程序示例,另含88张表格和115幅示意图。   《Linux/UNIX系统编程手册(上、下册)》总共分为64章,主要讲解了高效读写文件,对信号、时钟和定时器的运用,创建程、执行程序,编写安全的应用程序,运用POSIX线程技术编写多线程程序,创建和使用共享库,运用管道、消息队列、共享内存和信号量技术来行程间通信,以及运用套字API编写网络应用等内容。   《Linux/UNIX系统编程手册(上、下册)》在汇聚大批 Linux专有特性(epoll、inotify、/proc)的同时,还特意强化了对UNIX标准(POSIX、SUS)的论述,彻底达到了“鱼与熊掌,二者得兼”的效果,这也堪称本书的*亮。   《Linux/UNIX系统编程手册(上、下册)》布局合理,论述清晰,说理透彻,尤其是作者对示例代码的构思巧妙,独具匠心,仔细研读定会受益良多。本书适合从事Linux/UNIX系统发、运维工作的技术人员阅读,同时也可作为高校计算机专业学生的参考研习资料。 《Linux/UNIX系统编程手册(上、下册)》是介绍Linux与UNIX编程口的权威著作。Linux编程资深专家Michael Kerrisk在书中详细描述了Linux/UNIX系统编程所涉及的系统调用和库函数,并辅之以全面而清晰的代码示例。《Linux/UNIX系统编程手册(上、下册)》涵盖了逾500个系统调用及库函数,并给出逾200个程序示例,另含88张表格和115幅示意图。 《Linux/UNIX系统编程手册(上、下册)》总共分为64章,主要讲解了高效读写文件,对信号、时钟和定时器的运用,创建程、执行程序,编写安全的应用程序,运用POSIX线程技术编写多线程程序,创建和使用共享库,运用管道、消息队列、共享内存和信号量技术来行程间通信,以及运用套字API编写网络应用等内容。 《Linux/UNIX系统编程手册(上、下册)》在汇聚大批 Linux专有特性(epoll、inotify、/proc)的同时,还特意强化了对UNIX标准(POSIX、SUS)的论述,彻底达到了“鱼与熊掌,二者得兼”的效果,这也堪称本书的*亮。 《Linux/UNIX系统编程手册(上、下册)》布局合理,论述清晰,说理透彻,尤其是作者对示例代码的构思巧妙,独具匠心,仔细研读定会受益良多。本书适合从事Linux/UNIX系统发、运维工作的技术人员阅读,同时也可作为高校计算机专业学生的参考研习资料。
【推荐语】
Linux/UNIX系统编程口权威巨著,无出其右; 涵盖500多个系统调用和库函数;示例清晰完整,解释巨细靡遗; 涵盖当前UNIX标准(POSI X.1-2001/SUS v3和POSI X.1-2008/SUS v4); 众多业内专家人士联袂推荐; Linux/UNIX发人员的案头必备,注定成为新的经典;
【作者】
全球*的Linux内核黑客; 具有20多年的UNIX系统使用和编程经验; 自2004年起,始维护手册页项目(该项目旨在生成描述Linux内核以及glibc编程API的手册页); 撰写或合著了250多篇手册页; 极参与对Linux内核/用户空间口的测试和设计评审工作。
目录展开

总目录

上册

目录

内容提要

献辞

对本书的赞誉

前言

主题

本书的读者

Linux和UNIX

本书的用途和组织结构

程序示例

习题

标准和可移植性

Linux内核和C语言函数库版本

在其他语言中调用编程接口

关于作者

致谢

感谢Alejandro Forero Cuervo对本书书名的建议!

许可

Web站点和程序示例的源码

反馈

第1章 历史和标准

1.1 UNIX和C语言简史

UNIX的第一版到第六版

BSD和System V的诞生

1.2 Linux简史

1.2.1 GNU项目

1.2.2 Linux内核

题外话:BSD

Linux内核版本号

向其他硬件架构的移植

Linux发行版

1.3 标准化

1.3.1 C编程语言

1.3.2 首个POSIX标准

POSIX.1和POSIX.2

F151-1和FIPS 151-2

1.3.3 X/Open公司和The Open Group

1.3.4 SUSv3和POSIX.1-2001

符合POSIX、XSI规范和XSI扩展

未定义和未明确定义的接口

LEGACY(传统)特性

1.3.5 SUSv4和POSIX.1-2008

1.3.6 UNIX标准时间表

1.3.7 实现标准

1.3.8 Linux、标准、Linux标准规范(Linux Standard Base)

1.4 总结

进阶阅读

第2章 基本概念

2.1 操作系统的核心——内核

内核的职责

内核态和用户态

以进程及内核视角检视系统

进阶阅读

2.2 shell

2.3 用户和组

用户

超级用户

2.4 单根目录层级、目录、链接及文件

文件类型

路径和链接

符号链接

文件名

路径名

当前工作目录

文件的所有权和权限

2.5 文件I/O模型

文件描述符

stdio函数库

2.6 程序

过滤器

命令行参数

2.7 进程

进程的内存布局

创建进程和执行程序

进程ID和父进程ID

进程终止和终止状态

进程的用户和组标识符(凭证)

特权进程

能力(Capabilities)

init进程

守护进程

环境列表

资源限制

2.8 内存映射

2.9 静态库和共享库

静态库

共享库

2.10 进程间通信及同步

2.11 信号

2.12 线程

2.13 进程组和shell任务控制

2.14 会话、控制终端和控制进程

2.15 伪终端

2.16 日期和时间

2.17 客户端/服务器架构

2.18 实时性

2.19 /proc文件系统

2.20 总结

第3章 系统编程概念

3.1 系统调用

3.2 库函数

3.3 标准C语言函数库;GNU C语言函数库(glibc)

确定系统的glibc版本

3.4 处理来自系统调用和库函数的错误

处理系统调用错误

处理来自库函数的错误

3.5 关于本书示例程序的注意事项

3.5.1 命令行选项及参数

3.5.2 常用的函数及头文件

常用的头文件

错误诊断函数

解析数值型命令行参数的函数

3.6 可移植性问题

3.6.1 特性测试宏

_POSIX_SOURCE

_POSIX_C_SOURCE

_XOPEN_SOURCE

_BSD_SOURCE

_SVID_SOURCE

_GNU_SOURCE

_POSIX_C_SOURCE、_XOPEN_SOURCE以及POSIX.1/SUS

函数原型及源码示例中的特性测试宏

3.6.2 系统数据类型

打印系统数据类型值

3.6.3 其他的可移植性问题

初始化操作和使用结构

使用未见诸于所有实现的宏

不同实现间所需头文件的变化

3.7 总结

3.8 练习

第4章 文件I/O:通用的I/O模型

4.1 概述

4.2 通用I/O

4.3 打开一个文件:open()

open()调用所返回的文件描述符数值

4.3.1 open()调用中的flags参数

O_APPEND

O_ASYNC

O_CLOEXEC(自Linux 2.6.23版本开始支持)

O_CREAT

O_DIRECT

O_DIRECTORY

O_DSYNC(自Linux 2.6.33版本开始支持)

O_EXCL

O_LARGEFILE

O_NOATIME(自Linux 2.6.8版本开始)

O_NOCTTY

O_NOFOLLOW

O_NONBLOCK

O_SYNC

O_TRUNC

4.3.2 open()函数的错误

EACCES

EISDIR

EMFILE

ENFILE

ENOENT

EROFS

ETXTBSY

4.3.3 creat()系统调用

4.4 读取文件内容:read()

4.5 数据写入文件:write()

4.6 关闭文件:close()

4.7 改变文件偏移量:lseek()

SEEK_SET

SEEK_CUR

SEEK_END

文件空洞

示例程序

4.8 通用I/O模型以外的操作:ioctl()

4.9 总结

4.10 练习

第5章 深入探究文件I/O

5.1 原子操作和竞争条件

以独占方式创建一个文件

向文件尾部追加数据

5.2 文件控制操作:fcntl()

5.3 打开文件的状态标志

5.4 文件描述符和打开文件之间的关系

5.5 复制文件描述符

5.6 在文件特定偏移量处的I/O:pread()和pwrite()

5.7 分散输入和集中输出(Scatter-Gather I/O):readv()

分散输入

集中输出

在指定的文件偏移量处执行分散输入/集中输出

5.8 截断文件:truncate()和ftruncate()系统调用

5.9 非阻塞I/O

5.10 大文件I/O

过渡型LFS API

_FILE_OFFSET_BITS宏

向printf()调用传递off_t值

5.11 /dev/fd目录

5.12 创建临时文件

5.13 总结

5.14 练习

第6章 进程

6.1 进程和程序

6.2 进程号和父进程号

6.3 进程内存布局

6.4 虚拟内存管理

6.5 栈和栈帧

6.6 命令行参数(argc, argv)

6.7 环境列表

从程序中访问环境

修改环境

程序示例

6.8 执行非局部跳转:setjmp()和longjmp()

程序示例

对setjmp()函数的使用限制

滥用longjmp()

优化编译器的问题

尽可能避免使用setjmp()函数和longjmp()函数

6.9 总结

更多资料

6.9 练习

第7章 内存分配

7.1 在堆上分配内存

7.1.1 调整program break:brk()和sbrk()

7.1.2 在堆上分配内存:malloc()和free()

程序示例

调用free()还是不调用free()

7.1.3 malloc()和free()的实现

malloc调试的工具和库

控制和监测malloc函数包

7.1.4 在堆上分配内存的其他方法

用calloc()和realloc()分配内存

分配对齐的内存:memalign()和posix_memalign()

7.2 在堆栈上分配内存:alloca()

7.3 总结

7.4 练习

第8章 用户和组

8.1 密码文件:/etc/passwd

8.2 shadow密码文件:/etc/shadow

8.3 组文件:/etc/group

8.4 获取用户和组的信息

从密码文件获取记录

从组文件获取记录

程序示例

扫描密码文件和组文件中的所有记录

从shadow密码文件中获取记录

8.5 密码加密和用户认证

程序示例

8.6 总结

8.7 练习

第9章 进程凭证

9.1 实际用户ID和实际组ID

9.2 有效用户ID和有效组ID

9.3 Set-User-ID和Set-Group-ID程序

9.4 保存set-user-ID和保存set-group-ID

9.5 文件系统用户ID和组ID

9.6 辅助组ID

9.7 获取和修改进程凭证

9.7.1 获取和修改实际、有效和保存设置标识

获取实际和有效ID

修改有效ID

修改实际ID和有效ID

获取实际、有效和保存设置ID

修改实际、有效和保存设置ID

9.7.2 获取和修改文件系统ID

9.7.3 获取和修改辅助组ID

9.7.4 修改进程凭证的系统调用总结

9.7.5 示例:显示进程凭证

9.8 总结

9.9 习题

第10章 时间

10.1 日历时间(Calendar Time)

10.2 时间转换函数

10.2.1 将time_t转换为可打印格式

10.2.2 time_t和分解时间之间的转换

10.2.3 分解时间和打印格式之间的转换

从分解时间转换为打印格式

将打印格式时间转换为分解时间

10.3 时区

时区定义

为程序指定时区

10.4 地区(Locale)

地区定义

为程序设置地区

10.5 更新系统时钟

10.6 软件时钟(jiffies)

10.7 进程时间

示例程序

10.8 总结

进一步的信息

10.9 练习

第11章 系统限制和选项

11.1 系统限制

运行时恒定值(可能不确定)

路径名变量值

运行时可增加值

对选定SUSv3限制的总结

从shell中获取限制和选项:getconf

11.2 在运行时获取系统限制(和选项)

11.3 运行时获取与文件相关的限制(和选项)

11.4 不确定的限制

11.5 系统选项

11.6 总结

更多信息

11.7 练习

第12章 系统和进程信息

12.1 /proc文件系统

12.1.1 获取与进程有关的信息:/proc/PID

/proc/PID/fd目录

线程:/proc/PID/task目录

12.1.2 /proc 目录下的系统信息

12.1.3 访问/proc文件

访问/proc/PID目录中的文件

示例程序

12.2 系统标识:uname()

12.3 总结

进阶信息

12.4 练习

第13章 文件I/O缓冲

13.1 文件I/O的内核缓冲:缓冲区高速缓存

缓冲区大小对I/O系统调用性能的影响

13.2 stdio库的缓冲

设置一个stdio流的缓冲模式

_IONBF

_IOLBF

_IOFBF

刷新stdio缓冲区

13.3 控制文件I/O的内核缓冲

同步I/O数据完整性和同步I/O文件完整性

用于控制文件I/O内核缓冲的系统调用

使所有写入同步:O_SYNC

O_SYNC 对性能的影响

O_DSYNC和O_RSYNC标志

13.4 I/O缓冲小结

13.5 就I/O模式向内核提出建议

POSIX_FADV_NORMAL

POSIX_FADV_SEQUENTIAL

POSIX_FADV_RANDOM

POSIX_FADV_WILLNEED

POSIX_FADV_DONTNEED

POSIX_FADV_NOREUSE

13.6 绕过缓冲区高速缓存:直接I/O

直接I/O的对齐限制

示例程序

13.7 混合使用库函数和系统调用进行文件I/O

13.8 总结

补充信息

13.9 练习

第14章 系统编程概念

14.1 设备专用文件(设备文件)

设备ID

14.2 磁盘和分区

磁盘驱动器

磁盘分区

14.3 文件系统

ext2文件系统

文件系统结构

14.4 i节点

ext2中的i节点和数据块指针

14.5 虚拟文件系统(VFS)

14.6 日志文件系统

14.7 单根目录层级和挂载点

14.8 文件系统的挂载和卸载

14.8.1 挂载文件系统:mount()

MS_BIND(始于Linux 2.4)

MS_DIRSYNC(始于Linux 2.6)

MS_MANDLOCK

MS_MOVE

MS_NOATIME

MS_NODEV

MS_NODIRATIME

MS_NOEXEC

MS_NOSUID

MS_RDONLY

MS_REC(始于Linux 2.4.11)

MS_RELATIME (始于Linux 2.6.20)

MS_REMOUNT

MS_STRICTATIME(始于 Linux 2.6.30)

MS_SYNCHRONOUS

程序示例

14.8.2 卸载文件系统:umount()和umount2()

MNT_DETACH(始于Linux 2.4.11)

MNT_EXPIRE (始于Linux 2.6.8)

MNT_FORCE

UMOUNT_NOFOLLOW(始于Linux 2.6.34)

14.9 高级挂载特性

14.9.1 在多个挂载点挂载文件系统

14.9.2 多次挂载同一挂载点

14.9.3 基于每次挂载的挂载标志

14.9.4 绑定挂载

14.9.5 递归绑定挂载

14.10 虚拟内存文件系统:tmpfs

14.11 获得与文件系统有关的信息:statvfs()

14.12 总结

进阶阅读

14.13 练习

第15章 文件属性

15.1 获取文件信息:stat()

设备ID和i节点号

文件所有权

链接数

文件类型及权限

文件大小、已分配块以及最优I/O块大小

文件时间戳

程序示例

15.2 文件时间戳

纳秒时间戳

15.2.1 使用utime()和utimes()来改变文件时间戳

15.2.2 使用utimensat()和futimens()改变文件时间戳

15.3 文件属主

15.3.1 新建文件的属主

15.3.2 改变文件属主:chown()、fchown()和lchown()

15.4 文件权限

15.4.1 普通文件的权限

15.4.2 目录权限

15.4.3 权限检查算法

检查特权级别进程的权限

15.4.4 检查对文件的访问权限:access()

15.4.5 Set-User-ID、Set-Group-ID和Sticky位

15.4.6 进程的文件模式创建掩码:umask()

15.4.7 更改文件权限:chmod()和fchmod()

15.5 i节点标志(ext2扩展文件属性)

FS_APPEND_FL

FS_COMPR_FL

FS_DIRSYNC_FL(自Linux 2.6以后)

FS_IMMUTABLE_FL

FS_JOURNAL_DATA_FL

FS_NOATIME_FL

FS_NODUMP_FL

FS_NOTAIL_FL

FS_SECRM_FL

FS_SYNC_FL

FS_TOPDIR_FL(自Linux 2.6起)

FS_UNRM_FL

15.6 总结

15.7 练习

第16章 扩展属性

16.1 概述

EA命名空间

通过shell创建并查看EA

16.2 扩展属性的实现细节

对user扩展属性的限制

EA在实现方面的限制

16.3 操控扩展属性的系统调用

创建和修改EA

XATTR_CREATE

XATTR_REPLACE

获取EA值

删除EA

获取与文件相关联的所有EA的名称

程序示例

16.4 总结

16.5 练习

第17章 访问控制列表

17.1 概述

ACL记录

ACL_USER_OBJ

ACL_USER

ACL_GROUP_OBJ

ACL_GROUP

ACL_MASK

ACL_OTHER

最小ACL和扩展ACL

17.2 ACL权限检查算法

17.3 ACL的长、短文本格式

17.4 ACL_mask型ACE和ACL组分类

17.5 getfacl和setfacl命令

17.6 默认ACL与文件创建

17.7 ACL在实现方面的限制

17.8 ACL API

概述

将文件的ACL读入内存

从内存ACL中获取记录

获取并修改ACL记录中的属性

创建和删除ACE

更新文件的ACL

ACL在内存和文本格式之间的转换

ACL API中的其他函数

程序示例

17.9 总结

进阶信息

17.10 练习

第18章 目录与链接

18.1 目录和(硬)链接

18.2 符号(软)链接

系统调用对符号链接的解释

符号链接的文件权限和所有权

18.3 创建和移除(硬)链接:link()和 unlink()

仅当关闭所有文件描述符时,方可删除一个已打开的文件

18.4 更改文件名:rename()

18.5 使用符号链接:symlink()和readlink()

18.6 创建和移除目录:mkdir()和rmdir()

18.7 移除一个文件或目录:remove()

18.8 读目录:opendir()和readdir()

目录流与文件描述符

示例程序

readdir_r()函数

18.9 文件树遍历:nftw()

FTW_CHDIR

FTW_DEPTH

FTW_MOUNT

FTW_PHYS

FTW_D

FTW_DNR

FTW_DP

FTW_F

FTW_NS

FTW_SL

FTW_SLN

示例程序

nftw()的FTW_ACTIONRETVAL标识

FTW_CONTINUE

FTW_SKIP_SIBLINGS.

FTW_SKIP_SUBTREE

FTW_STOP

18.10 进程的当前工作目录

获取当前工作目录

改变当前工作目录

18.11 针对目录文件描述符的相关操作

18.12 改变进程的根目录:chroot()

18.13 解析路径名:realpath()

18.14 解析路径名字符串:dirname()和basename()

18.15 总结

18.16 练习

第19章 监控文件事件

19.1 概述

19.2 inotify API

19.3 inotify事件

19.4 读取inotify事件

程序示例

19.5 队列限制和/proc文件

max_queued_events

max_user_instances

max_user_watches

19.6 监控文件的旧有系统:dnotify

19.7 总结

19.8 练习

第20章 信号:基本概念

20.1 概念和概述

20.2 信号类型和默认行为

SIGABRT

SIGALRM

SIGBUS

SIGCHLD

SIGCLD

SIGCONT

SIGEMT

SIGFPE

SIGHUP

SIGILL

SIGINFO

SIGINT

SIGIO

SIGIOT

SIGKILL

SIGLOST

SIGPIPE

SIGPOLL

SIGPROF

SIGPWR

SIGQUIT

SIGSEGV

SIGSTKFLT

SIGSTOP

SIGSYS

SIGTERM

SIGTRAP

SIGTSTP

SIGTTIN

SIGTTOU

SIGUNUSED

SIGURG

SIGUSR1

SIGUSR2

SIGVTALRM

SIGWINCH

SIGXCPU

SIGXFSZ

20.3 改变信号处置:signal()

SIG_DFL

SIG_IGN

20.4 信号处理器简介

20.5 发送信号:kill()

20.6 检查进程的存在

20.7 发送信号的其他方式:raise()和killpg()

20.8 显示信号描述

20.9 信号集

示例程序

20.10 信号掩码(阻塞信号传递)

SIG_BLOCK

SIG_UNBLOCK

SIG_SETMASK

20.11 处于等待状态的信号

20.12 不对信号进行排队处理

20.13 改变信号处置:sigaction ()

SA_NOCLDSTOP

SA_NOCLDWAIT

SA_NODEFER

SA_ONSTACK

SA_RESETHAND

SA_RESTART

SA_SIGINFO

20.14 等待信号:pause()

20.15 总结

更多信息

20.16 练习

第21章 信号:信号处理器函数

21.1 设计信号处理器函数

21.1.1 再论信号的非队列化处理

21.1.2 可重入函数和异步信号安全函数

可重入和非可重入函数

示例程序

标准的异步信号安全函数

信号处理器函数内部对errno的使用

在本书示例程序中使用不安全函数

21.1.3 全局变量和sig_atomic_t数据类型

21.2 终止信号处理器函数的其他方法

21.2.1 在信号处理器函数中执行非本地跳转

示例程序

21.2.2 异常终止进程:abort()

21.3 在备选栈中处理信号:sigaltstack()

SS_ONSTACK

SS_DISABLE

21.4 SA_SIGINFO标志

结构siginfo_t

si_signo

si_code

si_value

si_pid

si_uid

si_errno

si_addr

si_timerid

si_overrun

si_band

si_fd

si_status

si_utime

si_stime

参数ucontext

21.5 系统调用的中断和重启

SA_RESTART标志对哪些系统调用(和库函数)有效

为信号修改SA_RESTART标志

对于某些Linux系统调用,未处理的停止信号会产生EINTR错误

21.6 总结

更多信息

21.7 练习

第22章 信号:高级特性

22.1 核心转储文件

不产生核心转储文件的情况

为核心转储文件命名:/proc/sys/kernel/core_pattern

22.2 传递、处置及处理的特殊情况

SIGKILL和SIGSTOP

SIGCONT和停止信号

由终端产生的信号若已被忽略,则不应改变其信号处置

22.3 可中断和不可中断的进程睡眠状态

22.4 硬件产生的信号

22.5 信号的同步生成和异步生成

22.6 信号传递的时机与顺序

何时传递一个信号?

解除对多个信号的阻塞时,信号的传递顺序

22.7 signal()的实现及可移植性

glibc的一些细节

sigaction()是建立信号处理器的首选API

22.8 实时信号

对排队实时信号的数量限制

使用实时信号

22.8.1 发送实时信号

22.8.2 处理实时信号

22.9 使用掩码来等待信号:sigsuspend()

示例程序

22.10 以同步方式等待信号

22.11 通过文件描述符来获取信号

SFD_CLOEXEC

SFD_NONBLOCK

22.12 利用信号进行进程间通信

22.13 早期的信号API(System V和BSD)

System V信号API

BSD信号API

22.14 总结

更多信息

22.15 练习

第23章 定时器与休眠

23.1 间隔定时器

ITIMER_REAL

ITIMER_VIRTUAL

ITIMER_PROF

示例程序

更为简单的定时器接口:alarm()

setitimer()和alarm()之间的交互

23.2 定时器的调度及精度

高分辨率定时器

23.3 为阻塞操作设置超时

23.4 暂停运行(休眠)一段固定时间

23.4.1 低分辨率休眠:sleep()

23.4.2 高分辨率休眠:nanosleep()

23.5 POSIX时钟

23.5.1 获取时钟的值:clock_gettime()

23.5.2 设置时钟的值:clock_settime()

23.5.3 获取特定进程或线程的时钟ID

23.5.4 高分辨率休眠的改进版:clock_nanosleep()

23.6 POSIX间隔式定时器

23.6.1 创建定时器:timer_create()

SIGEV_NONE

SIGEV_SIGNAL

SIGEV_THREAD

SIGEV_THREAD_ID

23.6.2 配备和解除定时器:timer_settime()

23.6.3 获取定时器的当前值:timer_gettime()

23.6.4 删除定时器:timer_delete()

23.6.5 通过信号发出通知

23.6.6 定时器溢出

23.6.7 通过线程来通知

23.7 利用文件描述符进行通知的定时器:timerfd API

TFD_CLOEXEC

TFD_NONBLOCK

timerfd与fork()及exec()之间的交互

从timerfd文件描述符读取

示例程序

23.8 总结

更多信息

23.9 练习

第24章 进程的创建

24.1 fork()、exit()、wait()以及execve()的简介

24.2 创建新进程:fork()

24.2.1 父、子进程间的文件共享

24.2.2 fork()的内存语义

控制进程的内存需求

24.3 系统调用vfork()

24.4 fork()之后的竞争条件(Race Condition)

24.5 同步信号以规避竞争条件

24.6 总结

更多信息

24.7 练习

第25章 进程的终止

25.1 进程的终止:_exit()和exit()

25.2 进程终止的细节

25.3 退出处理程序

注册退出处理程序

程序范例

25.4 fork()、stdio缓冲区以及_exit()之间的交互

25.5 总结

更多信息

25.6 练习

第26章 监控子进程

26.1 等待子进程

26.1.1 系统调用wait()

26.1.2 系统调用waitpid()

WUNTRACED

WCONTINUED (自Linux2.6.10以来)

WNOHANG

26.1.3 等待状态值

WIFEXITED (status)

WIFSIGNALED (status)

WIFSTOPPED (status)

WIFCONTINUED (status)

示例程序

26.1.4 从信号处理程序中终止进程

26.1.5 系统调用waitid()

WEXITED

WSTOPPED

WCONTINUED

WNOHANG

WNOWAIT

si_code

si_pid

si_signo

si_status

si_uid

26.1.6 系统调用wait3()和wait4()

26.2 孤儿进程与僵尸进程

26.3 SIGCHLD信号

26.3.1 为SIGCHLD建立信号处理程序

SIGCHLD处理程序的设计问题

范例程序

26.3.2 向已停止的子进程发送SIGCHLD信号

26.3.3 忽略终止的子进程

老版本Linux内核实现与SUSv3标准的差异

sigaction()的SA_NOCLDWAIT标志

系统V的SIGCLD信号

26.4 总结

更多信息

26.5 练习

第27章 程序的执行

27.1 执行新程序:execve()

EACCES

ENOENT

ENOEXEC

ETXTBSY

E2BIG

示例程序

27.2 exec()库函数

27.2.1 环境变量PATH

27.2.2 将程序参数指定为列表

27.2.3 将调用者的环境传递给新程序

27.2.4 执行由文件描述符指代的程序:fexecve()

27.3 解释器脚本

解释器脚本的执行

使用脚本的optional-arg(可选参数)

使用execlp()和execvp()执行脚本

27.4 文件描述符与exec()

执行时关闭(close-on-exec)标志(FD_CLOEXEC)

27.5 信号与exec()

27.6 执行shell命令:system()

示例程序

在设置用户ID(set-user-ID)和组ID(set-group-ID)程序中避免使用system()

27.7 system()的实现

对system()的简化实现

在system()内部正确处理信号

system()实现的改进版

关于system()的更多细节

27.8 总结

更多的信息

27.9 练习

第28章 详述进程创建和程序执行

28.1 进程记账

打开和关闭进程记账功能

进程账单记录

示例程序

进程记账文件格式(版本3)

28.2 系统调用clone()

示例程序

28.2.1 clone()的flags参数

共享文件描述符表:CLONE_FILES

共享与文件系统相关的信息:CLONE_FS

共享对信号的处置设置:CLONE_SIGHAND

共享父进程的虚拟内存:CLONE_VM

线程组:CLONE_THREAD

线程库支持:CLONE_PARENT_SETTID、CLONE_CHILD_SETTID和CLONE_CHILD_CLEARTID

线程本地存储:CLONE_SETTLS

共享System V信号量的撤销值:CLONE_SYSVSEM

每进程挂载命名空间:CLONE_NEWNS

将子进程的父进程置为调用者的父进程:CLONE_PARENT

将子进程的进程ID置为与父进程相同:CLONE_PID(已废止)

进程跟踪:CLONE_PTRACE和CLONE_UNTRACED

挂起(suspending)父进程直至子进程退出或调用exec():CLONE_VFORK

支持容器(container)的clone()新标志

clone()标志的使用

28.2.2 因克隆生成的子进程而对waitpid()进行的扩展

__WCLONE

__WALL(自Linux2.4之后)

__WNOTHREAD(自Linux2.4之后)

28.3 进程的创建速度

28.4 exec()和fork()对进程属性的影响

28.5 总结

更多信息

28.6 练习

第29章 线程:介绍

29.1 概述

29.2 Pthreads API的详细背景

线程数据类型(Pthreads data type)

线程和errno

Pthreads函数返回值

编译Pthreads程序

29.3 创建线程

29.4 终止线程

29.5 线程ID(Thread ID)

29.6 连接(joining)已终止的线程

示例程序

29.7 线程的分离

29.8 线程属性

29.9 线程VS进程

29.10 总结

进阶信息

29.11 练习

第30章 线程:线程同步

30.1 保护对共享变量的访问:互斥量

30.1.1 静态分配的互斥量

30.1.2 加锁和解锁互斥量

示例程序

pthread_mutex_trylock()和pthread_mutex_timedlock()

30.1.3 互斥量的性能

30.1.4 互斥量的死锁

30.1.5 动态初始化互斥量

30.1.6 互斥量的属性

30.1.7 互斥量类型

PTHREAD_MUTEX_NORMAL

PTHREAD_MUTEX_ERRORCHECK

PTHREAD_MUTEX_RECURSIVE

30.2 通知状态的改变:条件变量(Condition Variable)

30.2.1 由静态分配的条件变量

30.2.2 通知和等待条件变量

在生产者-消费者(producer-consumer)示例中使用条件变量

30.2.3 测试条件变量的判断条件(predicate)

30.2.4 示例程序:连接任意已终止线程

30.2.5 经由动态分配的条件变量

30.3 总结

更多信息

30.4 练习

第31章 线程:线程安全和每线程存储

31.1 线程安全(再论可重入性)

非线程安全的函数

可重入和不可重入函数

31.2 一次性初始化

31.3 线程特有数据

31.3.1 库函数视角下的线程特有数据

31.3.2 线程特有数据API概述

31.3.3 线程特有数据API详述

31.3.4 使用线程特有数据API

31.3.5 线程特有数据的实现限制

31.4 线程局部存储

31.5 总结

更多信息

31.6 练习

第32章 线程:线程取消

32.1 取消一个线程

32.2 取消状态及类型

PTHREAD_CANCEL_DISABLE

PTHREAD_CANCEL_ENABLE

PTHREAD_CANCEL_ASYNCHRONOUS

PTHREAD_CANCEL_DEFERED

32.3 取消点

示例程序

32.4 线程可取消性的检测

32.5 清理函数(cleanup handler)

示例程序

32.6 异步取消

32.7 总结

更多信息

第33章 线程:更多细节

33.1 线程栈

33.2 线程和信号

33.2.1 UNIX信号模型如何映射到线程中

33.2.2 操作线程信号掩码

33.2.3 向线程发送信号

33.2.4 妥善处理异步信号

33.3 线程和进程控制

线程和exec()

线程和fork()

线程与exit()

33.4 线程实现模型

多对一(M:1)实现(用户级线程)

一对一(1:1)实现(内核级线程)

多对多(M:N)实现(两级模型)

33.5 Linux POSIX线程的实现

33.5.1 LinuxThreads

LinuxThreds对标准行为的背离之处

LinuxThreads的其他问题

33.5.2 NPTL

NPTL标准一致性

33.5.3 哪一种线程实现

找出线程实现

NPTL 2.3.4

选择程序使用的线程实现

33.6 Pthread API的高级特性

33.7 总结

更多的信息

33.8 练习

下册

目录

第34章 进程组、会话和作业控制

34.1 概述

34.2 进程组

在作业控制shell中使用setpgid()

获取和修改进程组ID的其他(过时的)接口

34.3 会话

34.4 控制终端和控制进程

删除进程与控制终端之间的关联关系

在BSD上建立一个控制终端

获取表示控制终端的路径名:ctermid()

34.5 前台和后台进程组

34.6 SIGHUP信号

34.6.1 在shell中处理SIGHUP信号

34.6.2 SIGHUP和控制进程的终止

34.7 作业控制

34.7.1 在shell中使用作业控制

34.7.2 实现作业控制

SIGTTIN和SIGTTOU信号

示例程序:演示作业控制的操作

34.7.3 处理作业控制信号

示例程序

处理被忽略的任务控制和终端生成的信号

34.7.4 孤儿进程组(SIGHUP回顾)

示例程序

孤儿进程组和SIGTSTP、SIGTTIN、以及SIGTTOU信号

34.8 总结

更多信息

34.9 习题

第35章 进程优先级和调度

35.1 进程优先级(nice值)

nice值的影响

获取和修改优先级

PRIO_PROCESS

PRIO_PGRP

PRIO_USER

35.2 实时进程调度概述

POSIX实时与硬实时对比

35.2.1 SCHED_RR策略

35.2.2 SCHED_FIFO策略

35.2.3 SCHED_BATCH和SCHED_IDLE策略

35.3 实时进程调用API

35.3.1 实时优先级范围

35.3.2 修改和获取策略和优先级

修改调度策略和优先级

权限和资源限制会影响对调度参数的变更

获取调度策略和优先级

防止实时进程锁住系统

避免子进程进程特权调度策略

35.3.3 释放CPU

35.3.4 SCHED_RR时间片

35.4 CPU亲和力

35.5 总结

更多信息

35.6 习题

第36章 进程资源

36.1 进程资源使用

RUSAGE_SELF

RUSAGE_CHILDREN

RUSAGE_THREAD(自Linux 2.6.26起)

36.2 进程资源限制

示例程序

无法表示的限制值

36.3 特定资源限制细节

RLIMIT_AS

RLIMIT_CORE

RLIMIT_CPU

RLIMIT_DATA

RLIMIT_FSIZE

RLIMIT_MEMLOCK

RLIMIT_MSGQUEUE

RLIMIT_NICE

RLIMIT_NOFILE

RLIMIT_NPROC

RLIMIT_RSS

RLIMIT_RTPRIO

RLIMIT_RTTIME

RLIMIT_SIGPENDING

RLIMIT_STACK

36.4 总结

36.5 习题

第37章 DAEMON

37.1 概述

37.2 创建一个daemon

37.3 编写daemon指南

37.4 使用SIGHUP重新初始化一个daemon

37.5 使用syslog记录消息和错误

37.5.1 概述

37.5.2 syslog API

建立一个到系统日志的连接

LOG_CONS

LOG_NDELAY

LOG_NOWAIT

LOG_ODELAY

LOG_PERROR

LOG_PID

记录一条日志消息

关闭日志

过滤日志消息

37.5.3 /etc/syslog.conf文件

37.6 总结

更多信息

37.7 习题

第38章 编写安全的特权程序

38.1 是否需要一个Set-User-ID或Set-Group-ID程序

38.2 以最小权限操作

按需拥有权限

在无需使用权限时永久地删除权限

修改进程身份信息的注意事项

38.3 小心执行程序

在执行另一个程序之前永久地删除权限

避免执行一个拥有权限的shell(或其他解释器)

在exec()之前关闭所有用不到的文件描述符

38.4 避免暴露敏感信息

38.5 确定进程的边界

考虑使用能力

考虑使用一个chroot监牢

38.6 小心信号和竞争条件

38.7 执行文件操作和文件I/O的缺陷

38.8 不要完全相信输入和环境

不要信任环境列表

防御性地处理不可信用户的输入

避免对进程的运行时环境进行可靠性假设

38.9 小心缓冲区溢出

38.10 小心拒绝服务攻击

38.11 检查返回状态和安全地处理失败情况

38.12 总结

更多信息

38.13 习题

第39章 能力

39.1 能力基本原理

39.2 Linux能力

39.3 进程和文件能力

39.3.1 进程能力

39.3.2 文件能力

39.3.3 进程许可和有效能力集的目的

39.3.4 文件许可和有效能力集的目的

39.3.5 进程和文件可继承集的目的

39.3.6 在shell中给文件赋予能力和查看文件能力

39.4 现代能力实现

39.5 在exec()中转变进程能力

39.5.1 能力边界集

39.5.2 保持root语义

39.6 改变用户ID对进程能力的影响

39.7 用编程的方式改变进程能力

libcap API

示例程序

39.8 创建仅包含能力的环境

SECBIT_KEEP_CAPS和prctl() PR_SET_KEEPCAPS操作

39.9 发现程序所需的能力

39.10 不具备文件能力的老式内核和系统

CAP_SETPCAP能力

能力边界集

在运行于无文件能力的系统上的程序中使用能力

39.11 总结

39.12 习题

第40章 登录记账

40.1 utmp和wtmp文件概述

40.2 utmpx API

40.3 utmpx结构

EMPTY (0)

RUN_LVL (1)

BOOT_TIME (2)

NEW_TIME (3)

OLD_TIME (4)

INIT_PROCESS (5)

LOGIN_PROCESS (6)

USER_PROCESS (7)

DEAD_PROCESS (8)

40.4 从utmp和wtmp文件中检索信息

示例程序

40.5 获取登录名称:getlogin()

40.6 为登录会话更新utmp和wtmp文件

示例程序

40.7 lastlog文件

40.8 总结

更多信息

40.9 习题

第41章 共享库基础

41.1 目标库

题外话:在编译程序时包含调试器信息

41.2 静态库

创建和维护静态库

使用静态库

41.3 共享库概述

41.4 创建和使用共享库——首回合

41.4.1 创建一个共享库

41.4.2 位置独立的代码

41.4.3 使用一个共享库

LD_LIBRARY_PATH环境变量

静态链接和动态链接比较

41.4.4 共享库soname

41.5 使用共享库的有用工具

ldd命令

objdump和readelf命令

nm命令

41.6 共享库版本和命名规则

真实名称、soname以及链接器名称

使用标准规范创建一个共享库

41.7 安装共享库

ldconfig

41.8 兼容与不兼容库比较

41.9 升级共享库

41.10 在目标文件中指定库搜索目录

在构建共享库时使用–rpath链接器选项

ELF DT_RPATH和DT_RUNPATH条目

在rpath中使用$ORIGIN

41.11 在运行时找出共享库

41.12 运行时符号解析

41.13 使用静态库取代共享库

41.14 总结

更多信息

41.15 习题

第42章 共享库高级特性

42.1 动态加载库

42.1.1 打开共享库:dlopen()

RTLD_LAZY

RTLD_NOW

RTLD_GLOBAL

RTLD_LOCAL

RTLD_NODELETE(自glibc 2.2起)

RTLD_NOLOAD(自glibc 2.2起)

RTLD_DEEPBIND(自glibc 2.3.4)

42.1.2 错误诊断:dlerror()

42.1.3 获取符号的地址:dlsym()

在dlsym()中使用库伪句柄

RTLD_DEFAULT

RTLD_NEXT

示例程序

42.1.4 关闭共享库:dlclose()

42.1.5 获取与加载的符号相关的信息:dladdr()

42.1.6 在主程序中访问符号

42.2 控制符号的可见性

42.3 链接器版本脚本

42.3.1 使用版本脚本控制符号的可见性

42.3.2 符号版本化

42.4 初始化和终止函数

_init()和_fini()函数

42.5 预加载共享库

42.6 监控动态链接器:LD_DEBUG

42.7 总结

更多信息

42.8 习题

第43章 进程间通信简介

43.1 IPC工具分类

43.2 通信工具

数据传输

共享内存

43.3 同步工具

43.4 IPC工具比较

IPC对象标识和打开对象的句柄

功能

网络通信

可移植性

System V IPC设计问题

可访问性

持久性

性能

43.5 总结

43.6 习题

第44章 管道和FIFO

44.1 概述

一个管道是一个字节流

从管道中读取数据

管道是单向的

可以确保写入不超过PIPE_BUF字节的操作是原子的

管道的容量是有限的

44.2 创建和使用管道

管道允许相关进程间的通信

关闭未使用管道文件描述符

示例程序

44.3 将管道作为一种进程同步的方法

44.4 使用管道连接过滤器

示例程序

44.5 通过管道与shell命令进行通信:popen()

示例程序

44.6 管道和stdio缓冲

44.7 FIFO

使用FIFO和tee(1)创建双重管道线

44.8 使用管道实现一个客户端/服务器应用程序

应用程序概述

服务器程序

客户端程序

44.9 非阻塞I/O

非阻塞read()和write()

44.10 管道和FIFO中read()和write()的语义

44.11 总结

更多信息

44.12 习题

第45章 System V IPC介绍

45.1 概述

创建和打开一个System V IPC对象

IPC对象删除和对象持久

45.2 IPC Key

使用IPC_PRIVATE产生一个唯一的key

使用ftok()产生一个唯一的key

45.3 关联数据结构和对象权限

45.4 IPC标识符和客户端/服务器应用程序

45.5 System V IPC get调用使用的算法

45.6 ipcs和ipcrm命令

45.7 获取所有IPC对象列表

45.8 IPC限制

45.9 总结

更多信息

45.10 习题

第46章 System V消息队列

46.1 创建或打开一个消息队列

IPC_CREAT

IPC_EXCL

46.2 交换消息

46.2.1 发送消息

IPC_NOWAIT

46.2.2 接收消息

IPC_NOWAIT

MSG_EXCEPT

MSG_NOERROR

示例程序

46.3 消息队列控制操作

IPC_RMID

IPC_STAT

IPC_SET

46.4 消息队列关联数据结构

msg_perm

msg_stime

msg_rtime

msg_ctime

__msg_cbytes

msg_qnum

msg_qbytes

msg_lspid

msg_lrpid

46.5 消息队列的限制

MSGMNI

MSGMAX

MSGMNB

MSGTQL

MSGPOOL

46.6 显示系统中所有消息队列

46.7 使用消息队列实现客户端-服务器应用程序

服务器和客户端使用一个消息队列

一个客户端使用一个消息队列

46.8 使用消息队列实现文件服务器应用程序

公共头文件

服务器程序

客户端程序

46.9 System V消息队列的缺点

46.10 总结

46.11 习题

第47章 System V信号量

47.1 概述

47.2 创建或打开一个信号量集

IPC_CREAT

IPC_EXCL

47.3 信号量控制操作

常规控制操作

IPC_RMID

IPC_STAT

IPC_SET

获取和初始化信号量值

GETVAL

SETVAL

GETALL

SETALL

获取单个信号量的信息

GETPID

GETNCNT

GETZCNT

47.4 信号量关联数据结构

sem_perm

sem_otime

sem_ctime

sem_nsems

监控一个信号量集

初始化一个集合中的所有信号量

47.5 信号量初始化

47.6 信号量操作

示例程序

47.7 多个阻塞信号量操作的处理

47.8 信号量撤销值

SEM_UNDO的效果举例

SEM_UNDO的限制

47.9 实现一个二元信号量协议

47.10 信号量限制

SEMAEM

SEMMNI

SEMMSL

SEMMNS

SEMOPM

SEMVMX

SEMMNU

SEMUME

47.11 System V信号量的缺点

47.12 总结

更多信息

47.13 习题

第48章 System V共享内存

48.1 概述

48.2 创建或打开一个共享内存段

IPC_CREAT

IPC_EXCL

SHM_HUGETLB(自Linux 2.6起)

SHM_NORESERVE(自Linux 2.6.15起)

48.3 使用共享内存

48.4 示例:通过共享内存传输数据

48.5 共享内存在虚拟内存中的位置

48.6 在共享内存中存储指针

48.7 共享内存控制操作

常规控制操作

IPC_RMID

IPC_STAT

IPC_SET

加锁和解锁共享内存

48.8 共享内存关联数据结构

shm_perm

shm_segsz

shm_atime

shm_dtime

shm_ctime

shm_cpid

shm_lpid

shm_nattch

48.9 共享内存的限制

SHMMNI

SHMMIN

SHMMAX

SHMALL

SHMSEG

48.10 总结

更多信息

48.11 习题

第49章 内存映射

49.1 概述

49.2 创建一个映射:mmap()

MAP_PRIVATE

MAP_SHARED

有关内存保护的更多细节

标准中规定的对offset和addr的对齐约束

示例程序

49.3 解除映射区域:munmap()

49.4 文件映射

49.4.1 私有文件映射

49.4.2 共享文件映射

内存映射I/O

使用共享文件映射的IPC

示例程序

49.4.3 边界情况

49.4.4 内存保护和文件访问模式交互

49.5 同步映射区域:msync()

MS_SYNC

MS_ASYNC

MS_INVALIDATE

49.6 其他mmap()标记

MAP_ANONYMOUS

MAP_FIXED

MAP_HUGETLB(自Linux 2.6.32起)

MAP_LOCKED(自Linux 2.6起)

MAP_NORESERVE

MAP_POPULATE(自Linux 2.6起)

MAP_UNINITIALIZED(自Linux 2.6.33起)

49.7 匿名映射

MAP_ANONYMOUS和/dev/zero

MAP_PRIVATE匿名映射

MAP_SHARED匿名映射

示例程序

49.8 重新映射一个映射区域:mremap()

MREMAP_MAYMOVE

MREMAP_FIXED(自Linux 2.4起)

49.9 MAP_NORESERVE和过度利用交换空间

OOM杀手

49.10 MAP_FIXED标记

49.11 非线性映射:remap_file_pages()

49.12 总结

更多信息

49.13 习题

第50章 虚拟内存操作

50.1 改变内存保护:mprotect()

50.2 内存锁:mlock()和mlockatt()

RLIMIT_MEMLOCK资源限制

给内存区域加锁和解锁

内存加锁语义的细节信息

给一个进程占据的所有内存加锁和解锁

MCL_CURRENT

MCL_FUTURE

50.3 确定内存驻留性:mincore()

50.4 建议后续的内存使用模式:madvise()

MADV_NORMAL

MADV_RANDOM

MADV_SEQUENTIAL

MADV_WILLNEED

MADV_DONTNEED

50.5 小结

50.6 习题

第51章 POSIX IPC介绍

51.1 API概述

IPC对象名字

创建或打开IPC对象

O_CREAT

O_EXCL

关闭IPC对象

IPC对象权限

IPC对象删除和对象持久性

通过命令行列出和删除POSIX IPC对象

在Linux上编译使用POSIX IPC的程序

51.2 System V IPC与POSIX IPC比较

51.3 总结

第52章 POSIX消息队列

52.1 概述

52.2 打开、关闭和断开链接消息队列

打开一个消息队列

fork()、exec()以及进程终止对消息队列描述符的影响

关闭一个消息队列

删除一个消息队列

52.3 描述符和消息队列之间的关系

52.4 消息队列特性

在创建队列时设置消息队列特性

获取消息队列特性

mq_flags

mq_curmsgs

修改消息队列特性

52.5 交换消息

52.5.1 发送消息

52.5.2 接收消息

52.5.3 在发送和接收消息时设置超时时间

52.6 消息通知

SIGEV_NONE

SIGEV_SIGNAL

SIGEV_THREAD

52.6.1 通过信号接收通知

52.6.2 通过线程接收通知

52.7 Linux特有的特性

通过命令行显示和删除消息队列对象

获取消息队列的相关信息

使用另一种I/O模型操作消息队列

52.8 消息队列限制

MQ_PRIO_MAX

MQ_OPEN_MAX

msg_max

msgsize_max

queues_max

52.9 POSIX和System V消息队列比较

52.10 总结

更多信息

52.11 习题

第53章 POSIX信号量

53.1 概述

53.2 命名信号量

53.2.1 打开一个命名信号量

示例程序

53.2.2 关闭一个信号量

53.2.3 删除一个命名信号量

53.3 信号量操作

53.3.1 等待一个信号量

53.3.2 发布一个信号量

53.3.3 获取信号量的当前值

示例

53.4 未命名信号量

未命名与命名信号量对比

53.4.1 初始化一个未命名信号量

示例程序

53.4.2 销毁一个未命名信号量

53.5 与其他同步技术比较

POSIX信号量与System V信号量比较

POSIX信号量与Pthreads互斥体对比

53.6 信号量的限制

SEM_NSEMS_MAX

SEM_VALUE_MAX

53.7 总结

更多信息

53.8 习题

第54章 POSIX共享内存

54.1 概述

54.2 创建共享内存对象

示例程序

54.3 使用共享内存对象

54.4 删除共享内存对象

54.5 共享内存API比较

54.6 总结

54.7 习题

第55章 文件加锁

55.1 概述

混合使用加锁和stdio函数

劝告式和强制式加锁

55.2 使用flock()给文件加锁

55.2.1 锁继承与释放的语义

55.2.2 flock()的限制

55.3 使用fcntl()给记录加锁

flock结构

cmd参数

F_SETLK

F_SETLKW

F_GETLK

锁获取和释放的细节

55.3.1 死锁

55.3.2 示例:一个交互式加锁程序

55.3.3 示例:一个加锁函数库

55.3.4 锁的限制和性能

55.3.5 锁继承和释放的语义

55.3.6 锁定饿死和排队加锁请求的优先级

55.4 强制加锁

强制式加锁对文件I/O操作的影响

强制式加锁警告

55.5 /proc/locks文件

55.6 仅运行一个程序的单个实例

55.7 老式加锁技术

open(file, 0_CREAT | 0_EXCL,...)加上unlink(file)

link(file, lockfile)加上unlink(lockfile)

55.8 总结

更多信息

55.9 习题

第56章 SOCKET:介绍

56.1 概述

通信domain

socket类型

socket系统调用

56.2 创建一个socket:socket()

56.3 将socket绑定到地址:bind()

56.4 通用socket地址结构:struct sockaddr

56.5 流socket

主动和被动socket

56.5.1 监听接入连接:listen()

56.5.2 接受连接:accept()

56.5.3 连接到对等socket:connect()

56.5.4 流socket I/O

56.5.5 连接终止:close()

56.6 数据报socket

56.6.1 交换数据报:recvfrom和sendto()

56.6.2 在数据报socket上使用connect()

56.7 总结

更多信息

第57章 SOCKET:UNIX DOMAIN

57.1 UNIX domain socket地址:struct sockaddr_un

57.2 UNIX domain中的流socket

57.3 UNIX domain中的数据报socket

UNIX domain数据报socket能传输的数据报的最大大小

示例程序

57.4 UNIX domain socket权限

57.5 创建互联socket对:socketpair()

57.6 Linux抽象socket名空间

57.7 总结

更多信息

57.8 习题

第58章 SOCKET:TCP/IP网络基础

58.1 互联网

58.2 联网协议和层

封装

58.3 数据链路层

58.4 网络层:IP

IP传输数据报

IP是无连接和不可靠的

IP可能会对数据报进行分段

58.5 IP地址

IPv4地址

IPv6地址

58.6 传输层

58.6.1 端口号

众所周知的、注册的以及特权端口

临时端口

58.6.2 用户数据报协议(UDP)

选择一个UDP数据报大小以避免IP分段

58.6.3 传输控制协议(TCP)

连接建立

将数据打包成段

确认、重传以及超时

排序

流量控制

拥塞控制:慢启动和拥塞避免算法

58.7 请求注解(RFC)

58.8 总结

更多信息

第59章 SOCKET:Internet Domain

59.1 Internet domain socket

59.2 网络字节序

59.3 数据表示

59.4 Internet socket地址

IPv4 socket地址:struct sockaddr_in

IPv6 socket地址:struct sockaddr_in6

sockaddr_storage结构

59.5 主机和服务转换函数概述

在二进制和人类可读的形式之间转换IPv4地址

在二进制和人类可读的形式之间转换IPv4和IPv6地址

主机和服务名与二进制形式之间的转换(已过时)

主机和服务名与二进制形式之间的转换(现代的)

59.6 inet_pton()和inet_ntop()函数

59.7 客户端/服务器示例(数据报socket)

59.8 域名系统(DNS)

递归和迭代的解析请求

顶级域

59.9 /etc/services文件

59.10 独立于协议的主机和服务转换

59.10.1 getaddrinfo()函数

hints参数

AI_ADDRCONFIG

AI_ALL

AI_CANONNAME

AI_NUMERICHOST

AI_NUMERICSERV

AI_PASSIVE

AI_V4MAPPED

59.10.2 释放addrinfo列表:freeaddrinfo()

59.10.3 错误诊断:gai_strerror()

59.10.4 getnameinfo()函数

NI_DGRAM

NI_NAMEREQD

NI_NOFQDN

NI_NUMERICHOST

NI_NUMERICSERV

59.11 客户端/服务器示例(流式socket)

公共头文件

服务器程序

客户端程序

59.12 Internet domain socket库

59.13 过时的主机和服务转换API

59.13.1 inet_aton()和inet_ntoa()函数

59.13.2 gethostbyname()和gethostbyaddr()函数

59.13.3 getserverbyname()和getserverbyport()函数

59.14 UNIX与Internet domain socket比较

59.15 更多信息

59.16 总结

59.17 习题

第60章 SOCKET:服务器设计

60.1 迭代型和并发型服务器

60.2 迭代型UDP echo服务器

60.3 并发型TCP echo服务器

60.4 并发型服务器的其他设计方案

在服务器上预先创建进程或线程

在单个进程中处理多个客户端

采用服务器集群

60.5 inetd(Internet超级服务器)守护进程

inetd守护进程所做的操作

/etc/inetd.conf文件

示例:通过inetd调用一个TCP echo服务

60.6 总结

更多信息

60.7 练习

第61章 SOCKET:高级主题

61.1 流式套接字上的部分读和部分写

61.2 shutdown()系统调用

SHUT_RD

SHUT_WR

SHUT_RDWR

示例程序

61.3 专用于套接字的I/O系统调用:recv()和send()

MSG_DONTWAIT

MSG_OOB

MSG_PEEK

MSG_WAITALL

MSG_DONTWAIT

MSG_MORE(从Linux 2.4.4开始)

MSG_NOSIGNAL

MSG_OOB

61.4 sendfile()系统调用

TCP_CORK套接字选项

61.5 获取套接字地址

61.6 深入探讨TCP协议

61.6.1 TCP报文的格式

61.6.2 TCP序列号和确认机制

61.6.3 TCP协议状态机以及状态迁移图

61.6.4 TCP连接的建立

61.6.5 TCP连接的终止

61.6.6 在TCP套接字上调用shutdown()

61.6.7 TIME_WAIT状态

61.7 监视套接字:netstat

61.8 使用tcpdump来监视TCP流量

61.9 套接字选项

61.10 SO_REUSEADDR套接字选项

61.11 在accept()中继承标记和选项

61.12 TCP vs.UDP

61.13 高级功能

61.13.1 带外数据

61.13.2 sendmsg()和recvmsg()系统调用

61.13.3 传递文件描述符

61.13.4 接收发送端的凭据

61.13.5 顺序数据包套接字

61.13.6 SCTP以及DCCP传输层协议

61.14 总结

更多信息

61.15 练习

第62章 终端

62.1 整体概览

62.2 获取和修改终端属性

TCSANOW

TCSADRAIN

TCSAFLUSH

62.3 stty命令

62.4 终端特殊字符

CR

DISCARD

EOF

EOL以及EOL2

ERASE

INTR

KILL

LNEXT

NL

QUIT

REPRINT

START和STOP

SUSP

WERASE

其他的终端特殊字符

示例程序

62.5 终端标志

BRKINT

ECHO

ECHOCTL

ECHOE

ECHOK和ECHOKE

ICANON

IEXTEN

IMAXBEL

IUTF8

NOFLSH

OPOST

PARENB、IGNPAR、INPCK、PARMRK以及PARODD

示例程序

62.6 终端的I/O模式

62.6.1 规范模式

62.6.2 非规范模式

MIN == 0,TIME == 0 (轮询读取)

MIN > 0,TIME == 0(阻塞式读取)

MIN == 0,TIME > 0(带有超时机制的读操作)

MIN > 0,TIME > 0 (既有超时机制又有最小读取字节数的要求)

以可移植的方式修改并恢复MIN和TIME

62.6.3 加工模式、cbreak模式以及原始模式

示例程序

62.7 终端线速(比特率)

62.8 终端的行控制

62.9 终端窗口大小

62.10 终端标识

62.11 总结

更多信息

62.12 练习

第63章 其他备选的I/O模型

63.1 整体概览

选择哪种技术

63.1.1 水平触发和边缘触发

63.1.2 在备选的I/O模型中采用非阻塞I/O

63.2 I/O多路复用

63.2.1 select()系统调用

文件描述符集合

timeout参数

select()的返回值

示例程序

63.2.2 poll()系统调用

timeout参数

poll()的返回值

示例程序

63.2.3 文件描述符何时就绪

普通文件

终端和伪终端

管道和FIFO

套接字

63.2.4 比较select()和poll()

实现细节

API之间的区别

可移植性

性能

63.2.5 select()和poll()存在的问题

63.3 信号驱动I/O

示例程序

在启动信号驱动I/O前安装信号处理例程

设定文件描述符属主

63.3.1 何时发送“I/O就绪”信号

终端和伪终端

管道和FIFO

套接字

inotify文件描述符

63.3.2 优化信号驱动I/O的使用

信号队列溢出的处理

在多线程程序中使用信号驱动I/O

F_OWNER_PGRP

F_OWNER_PID

F_OWNER_TID

63.4 epoll编程接口

63.4.1 创建epoll实例:epoll_create()

63.4.2 修改epoll的兴趣列表:epoll_ctl()

EPOLL_CTL_ADD

EPOLL_CTL_MOD

EPOLL_CTL_DEL

max_user_watches上限

63.4.3 事件等待:epoll_wait()

epoll事件

EPOLLONESHOT标志

程序示例

63.4.4 深入探究epoll的语义

63.4.5 epoll同I/O多路复用的性能对比

63.4.6 边缘触发通知

当采用边缘触发通知时避免出现文件描述符饥饿现象

63.5 在信号和文件描述符上等待

63.5.1 pselect()系统调用

ppoll()和epoll_pwait()系统调用

63.5.2 self-pipe技巧

63.6 总结

更多信息

63.7 练习

第64章 伪终端

64.1 整体概览

伪终端主从设备

如何使用伪终端

伪终端的应用

System V(UNIX 98)和BSD伪终端

64.2 UNIX 98伪终端

64.2.1 打开未使用的主设备:posix_openpt()

O_RDWR

O_NOCTTY

UNIX 98伪终端数量的限制

64.2.2 修改从设备属主和权限:grantpt()

64.2.3 解锁从设备:unlockpt()

64.2.4 获取从设备名称:ptsname()

64.3 打开主设备:ptyMasterOpen()

64.4 将进程连接到伪终端:ptyFork()

64.5 伪终端I/O

信包模式

64.6 实现script(1)程序

64.7 终端属性和窗口大小

64.8 BSD风格的伪终端

64.9 总结

64.10 练习

附录A 跟踪系统调用

附录B 解析命令行选项

程序示例

特定于GNU的行为

GNU扩展

附录C 对NULL指针做转型

附录D 内核配置

附录E 更多信息源

手册

GNU info文档

GNU C库(glibc)手册

书籍

既有应用程序的源代码

Linux文档项目

GNU项目

新闻组

Linux内核邮件列表

网站

内核源代码

附录F 部分习题解答

第5章

第6章

第8章

第9章

第10章

第12章

第13章

第15章

第18章

第20章

第22章

第23章

第24章

第25章

第26章

第27章

第29章

第31章

第33章

第34章

第35章

第36章

第37章

第38章

第44章

第45章

第46章

第47章

第48章

第49章

第50章

第52章

第53章

第55章

第57章

第59章

第60章

第61章

第62章

第63章

第64章

累计评论(0条) 0个书友正在讨论这本书 发表评论

发表评论

发表评论,分享你的想法吧!

买过这本书的人还买过

读了这本书的人还在读

回顶部