您好,欢迎来到聚文网。 登录 免费注册
Linux环境编程

Linux环境编程

  • 装帧: 平装
  • 出版社: 机械工业出版社
  • 作者: 高峰,李彬 著
  • 出版日期: 2016-06-01
  • 商品条码: 9787111536109
  • 版次: 1
  • 开本: 16开
  • 页数: 596
  • 出版年份: 2016
定价:¥99 销售价:登录后查看价格  ¥{{selectedSku?.salePrice}} 
库存: {{selectedSku?.stock}} 库存充足
{{item.title}}:
{{its.name}}
精选
内容简介
本书将按照APUE的脉络,以笔者多年的Linux开发经验为基础,从以下四个方面深入讲解Linux环境编程:接口的功能使用介绍、接口缺陷分析、接口的内部实现机制、接口的错误码分析。本书将从一个全新的角度带领读者重新进入Linux环境编程,从应用出发,深入内核源码,研究Linux各接口的工作机制和原理。让读者不仅知其然,还知其所以然。
作者简介
高峰,北京理工大学通信与信息系统专业硕士。毕业后在A10 Networks公司工作六年多,任职Staff Software Engineer,目前是创业公司全讯汇聚(爱快路由)的技术合伙人。多年来一直专注于网络领域,熟悉Linux内核、应用及服务端的设计、开发和架构,对TCP/IP网络协议有深刻的认识和理解。编码功力深厚,知识领域广博,擅长产品的性能改进和调优。撰写过大量技术文章,并为多个知名开源项目贡献过代码。
李彬,东南大学信号与信息处理专业硕士。毕业后先后任职中兴通讯、趋势科技,目前在存储公司Bigtera担任SEG部门技术负责人。一直专注于Linux平台下的开发,多年分布式存储开发经验,熟悉Linux内核,编程基本功扎实,对性能优化、bug定位有异乎寻常的爱好,属于“死磕派”研发工程师。喜欢技术分享和交流,在社区和公司内部分享过大量技术文章。
目录
前言
第0章基础知识1
0.1一个Linux程序的诞生记1
0.2程序的构成2
0.3程序是如何“跑”的4
0.4背景概念介绍5
0.4.1系统调用5
0.4.2C库函数6
0.4.3线程安全7
0.4.4原子性9
0.4.5可重入函数9
0.4.6阻塞与非阻塞11
0.4.7同步与非同步11
第1章文件I/O12
1.1Linux中的文件12
1.1.1文件、文件描述符和文件表12
1.1.2内核文件表的实现13
1.2打开文件14
1.2.1open介绍14
1.2.2更多选项15
1.2.3open源码跟踪16
1.2.4如何选择文件描述符17
1.2.5文件描述符fd与文件管理结构file18
1.3creat简介19
1.4关闭文件19
1.4.1close介绍19
1.4.2close源码跟踪19
1.4.3自定义files_operations21
1.4.4遗忘close造成的问题22
1.4.5如何查找文件资源泄漏25
1.5文件偏移26
1.5.1lseek简介26
1.5.2小心lseek的返回值26
1.5.3lseek源码分析27
1.6读取文件29
1.6.1read源码跟踪29
1.6.2部分读取30
1.7写入文件31
1.7.1write源码跟踪31
1.7.2追加写的实现33
1.8文件的原子读写33
1.9文件描述符的复制34
1.10文件数据的同步38
1.11文件的元数据41
1.11.1获取文件的元数据41
1.11.2内核如何维护文件的元数据42
1.11.3权限位解析43
1.12文件截断45
1.12.1truncate与ftruncate的简单介绍45
1.12.2文件截断的内核实现45
1.12.3为什么需要文件截断48
第2章标准I/O库50
2.1stdin、stdout和stderr50
2.2I/O缓存引出的趣题51
2.3fopen和open标志位对比52
2.4fdopen与fileno55
2.5同时读写的痛苦56
2.6ferror的返回值57
2.7clearerr的用途57
2.8小心fgetc和getc60
2.9注意fread和fwrite的返回值60
2.10创建临时文件61
第3章进程环境66
3.1main是C程序的开始吗66
3.2“活雷锋”exit70
3.3atexit介绍75
3.3.1使用atexit75
3.3.2atexit的局限性76
3.3.3atexit的实现机制77
3.4小心使用环境变量78
3.5使用动态库80
3.5.1动态库与静态库80
3.5.2编译生成和使用动态库80
3.5.3程序的“平滑无缝”升级82
3.6避免内存问题84
3.6.1尴尬的realloc84
3.6.2如何防止内存越界85
3.6.3如何定位内存问题86
3.7“长跳转”longjmp90
3.7.1setjmp与longjmp的使用90
3.7.2“长跳转”的实现机制91
3.7.3“长跳转”的陷阱93
第4章进程控制:进程的一生96
4.1进程ID96
4.2进程的层次98
4.2.1进程组99
4.2.2会话102
4.3进程的创建之fork()103
4.3.1fork之后父子进程的内存关系104
4.3.2fork之后父子进程与文件的关系107
4.3.3文件描述符复制的内核实现110
4.4进程的创建之vfork()115
4.5daemon进程的创建117
4.6进程的终止119
4.6.1_exit函数119
4.6.2exit函数120
4.6.3return退出122
4.7等待子进程122
4.7.1僵尸进程122
4.7.2等待子进程之wait()124
4.7.3等待子进程之waitpid()126
4.7.4等待子进程之等待状态值129
4.7.5等待子进程之waitid()131
4.7.6进程退出和等待的内核实现133
4.8exec家族141
4.8.1execve函数141
4.8.2exec家族142
4.8.3execve系统调用的内核实现144
4.8.4exec与信号151
4.8.5执行exec之后进程继承的属性152
4.9system函数152
4.9.1system函数接口153
4.9.2system函数与信号156
4.10总结157
第5章进程控制:状态、调度和优先级158
5.1进程的状态158
5.1.1进程状态概述159
5.1.2观察进程状态171
5.2进程调度概述173
5.3普通进程的优先级181
5.4完全公平调度的实现186
5.4.1时间片和虚拟运行时间186
5.4.2周期性调度任务190
5.4.3新进程的加入192
5.4.4睡眠进程醒来198
5.4.5唤醒抢占202
5.5普通进程的组调度204
5.6实时进程207
5.6.1实时调度策略和优先级207
5.6.2实时调度相关API211
5.6.3限制实时进程运行时间213
5.7CPU的亲和力214
第6章信号219
6.1信号的完整生命周期219
6.2信号的产生220
6.2.1硬件异常220
6.2.2终端相关的信号221
6.2.3软件事件相关的信号223
6.3信号的默认处理函数224
6.4信号的分类227
6.5传统信号的特点228
6.5.1信号的ONESHOT特性230
6.5.2信号执行时屏蔽自身的特性232
6.5.3信号中断系统调用的重启特性233
6.6信号的可靠性236
6.6.1信号的可靠性实验236
6.6.2信号可靠性差异的根源240
6.7信号的安装243
6.8信号的发送246
6.8.1kill、tkill和tgkill246
6.8.2raise函数247
6.8.3sigqueue函数247
6.9信号与线程的关系253
6.9.1线程之间共享信号处理函数254
6.9.2线程有独立的阻塞信号掩码255
6.9.3私有挂起信号和共享挂起信号257
6.9.4致命信号下,进程组全体退出260
6.10等待信号260
6.10.1pause函数261
6.10.2sigsuspend函数262
6.10.3sigwait函数和sigwaitinfo函数263
6.11通过文件描述符来获取信号265
6.12信号递送的顺序267
6.13异步信号安全272
6.14总结275
第7章理解Linux线程(1)276
7.1线程与进程276
7.2进程ID和线程ID281
7.3pthread库接口介绍284
7.4线程的创建和标识285
7.4.1pthread_create函数285
7.4.2线程ID及进程地址空间布局286
7.4.3线程创建的默认属性291
7.5线程的退出292
7.6线程的连接与分离293
7.6.1线程的连接293
7.6.2为什么要连接退出的线程295
7.6.3线程的分离299
7.7互斥量300
7.7.1为什么需要互斥量300
7.7.2互斥量的接口304
7.7.3临界区的大小305
7.7.4互斥量的性能306
7.7.5互斥锁的公平性310
7.7.6互斥锁的类型311
7.7.7死锁和活锁314
7.8读写锁316
7.8.1读写锁的接口317
7.8.2读写锁的竞争策略318
7.8.3读写锁总结323
7.9性能杀手:伪共享323
7.10条件等待328
7.10.1条件变量的创建和销毁328
7.10.2条件变量的使用329
第8章理解Linux线程(2)333
8.1线程取消333
8.1.1函数取消接口333
8.1.2线程清理函数335
8.2线程局部存储339
8.2.1使用NPTL库函数实现线程局部存储340
8.2.2使用__thread关键字实现线程局部存储342
8.3线程与信号343
8.3.1设置线程的信号掩码344
8.3.2向线程发送信号344
8.3.3多线程程序对信号的处理345
8.4多线程与fork()345
第9章进程间通信:管道349
9.1管道351
9.1.1管道概述351
9.1.2管道接口352
9.1.3关闭未使用的管道文件描述符356
9.1.4管道对应的内存区大小361
9.1.5shell管道的实现361
9.1.6与shell命令进行通信(popen)362
9.2命名管道FIFO365
9.2.1创建FIFO文件365
9.2.2打开FIFO文件366
9.3读写管道文件367
9.4使用管道通信的示例372
第10章进程间通信:SystemVIPC375
10.1SystemVIPC概述375
10.1.1标识符与IPCKey376
10.1.2IPC的公共数据结构379
10.2SystemV消息队列383
10.2.1创建或打开一个消息队列383
10.2.2发送消息385
10.2.3接收消息388
10.2.4控制消息队列390
10.3SystemV信号量391
10.3.1信号量概述391
10.3.2创建或打开信号量393
10.3.3操作信号量395
10.3.4信号量撤销值399
10.3.5控制信号量400
10.4SystemV共享内存402
10.4.1共享内存概述402
10.4.2创建或打开共享内存403
10.4.3使用共享内存405
10.4.4分离共享内存407
10.4.5控制共享内存408
第11章进程间通信:POSIXIPC410
11.1POSIXIPC概述411
11.1.1IPC对象的名字411
11.1.2创建或打开IPC对象413
11.1.3关闭和删除IPC对象414
11.1.4其他414
11.2POSIX消息队列415
11.2.1消息队列的创建、打开、关闭及删除415
11.2.2消息队列的属性418
11.2.3消息的发送和接收422
11.2.4消息的通知423
11.2.5I/O多路复用监控消息队列427
11.3POSIX信号量428
11.3.1创建、打开、关闭和删除有名信号量430
11.3.2信号量的使用431
11.3.3无名信号量的创建和销毁432
11.3.4信号量与futex433
11.4内存映射mmap436
11.4.1内存映射概述436
11.4.2内存映射的相关接口438
11.4.3共享文件映射439
11.4.4私有文件映射455
11.4.5共享匿名映射455
11.4.6私有匿名映射456
11.5POSIX共享内存456
11.5.1共享内存的创建、使用和删除457
11.5.2共享内存与tmpfs458
第12章网络通信:连接的建立462
12.1socket文件描述符462
12.2绑定IP地址463
12.2.1bind的使用464
12.2.2bind的源码分析465
12.3客户端连接过程468
12.3.1connect的使用468
12.3.2connect的源码分析469
12.4服务器端连接过程477
12.4.1listen的使用477
12.4.2listen的源码分析478
12.4.3accept的使用480
12.4.4accept的源码分析480
12.5TCP三次握手的实现分析483
12.5.1SYN包的发送483
12.5.2接收SYN包,发送SYN+ACK包485
12.5.3接收SYN+ACK数据包494
12.5.4接收ACK数据包,完成三次握手499
第13章网络通信:数据报文的发送505
13.1发送相关接口505
13.2数据包从用户空间到内核空间的流程506
13.3UDP数据包的发送流程510
13.4TCP数据包的发送流程517
13.5IP数据包的发送流程527
13.5.1ip_send_skb源码分析528
13.5.2ip_queue_xmit源码分析531
13.6底层模块数据包的发送流程532
第14章网络通信:数据报文的接收536
14.1系统调用接口536
14.2数据包从内核空间到用户空间的流程537
14.3UDP数据包的接收流程540
14.4TCP数据包的接收流程544
14.5TCP套接字的三个接收队列553
14.6从网卡到套接字556
14.6.1从硬中断到软中断556
14.6.2软中断处理557
14.6.3传递给协议栈流程559
14.6.4IP协议处理流程564
14.6.5大师的错误?原始套接字的接收568
14.6.6注册传输层协议571
14.6.7确定UDP套接字571
14.6.8确定TCP套接字576
第15章编写安全无错代码582
15.1不要用memcmp比较结构体582
15.2有符号数和无符号数的移位区别583
15.3数组和指针584
15.4再论数组首地址587
15.5“神奇”的整数类型转换588
15.6小心volatile的原子性误解589
15.7有趣的问题:“x==x”何时为假?591
15.8小心浮点陷阱593
15.8.1浮点数的精度限制593
15.8.2两个特殊的浮点值593
15.9Intel移位指令陷阱595
摘要
Preface  前    言为什么要写这本书我从事Linux环境的开发工作已有近十年的时间,但我一直认为工作时间并不等于经验,更不等于能力。如何才能把工作时间转换为自己的经验和能力呢?我认为无非是多阅读、多思考、多实践、多分享。这也是我在ChinaUnix上的博客座右铭,目前我的博客一共有247篇博文,记录的大都是Linux内核网络部分的源码分析,以及相关的应用编程。机械工业出版社华章公司的Lisa正是通过我的博客找到我的,而这也促成了本书的出版。
    其实在Lisa之前,就有另外一位编辑与我聊过,但当时我没有下好决心,认为自己无论是在技术水平,还是时间安排上,都不足以完成一本技术图书的创作。等到与Lisa洽谈的时候,我感觉自己的技术已经有了一些沉淀,同时时间也相对比较充裕,因此决定开始撰写自己技术生涯的第一本书。
    对于Linux环境的开发人员,《Unix环境高级编程》(后文均简称为APUE)无疑是最为经典的入门书籍。其作者Stevens是我从业以来最崇拜的技术专家。他的Advanced Programming in the Unix Environment、Unix Network Programming系列及TCP/IP Illustrated系列著作,字字珠玑,本本经典。在我从业的最初几年,这几本书每本都阅读了好几遍,而这也为我进行Linux用户空间的开发奠定了坚实的基础。在掌握了这些知识以后,如何继续提高自己的技能呢?经过一番思考,我选择了阅读Linux内核源码,并尝试将内核与应用融会贯通。在阅读了一定量的内核源码之后,我才真正理解了Linux专家的这句话“Read the fucking codes”。只有阅读了内核源码,才能真正理解Linux内核的原理和运行机制,而此时,我也发现了Stevens著作的一个局限—APUE和UNP毕竟是针对Unix环境而写的,Linux虽然大部分与Unix兼容,但是在很多行为上与Unix还是完全不同的。这就导致了书中的一些内容与Linux环境中的实际效果是相互矛盾的。
    现在有机会来写一本技术图书,我就想在向Stevens致敬的同时,写一本类似于APUE风格的技术图书,同时还要在Linux环境下,对APUE进行突破。大言不惭地说,我期待这本书可以作为APUE的补充,还可以作为Linux开发人员的进阶读物。事实上,本书的写作布局正是以APUE的章节作为参考,针对Linux环境,不仅对用户空间的接口进行阐述,同时还引导读者分析该接口在内核的源码实现,使得读者不仅可以知道接口怎么用,同时还可以理解接口是怎么工作的。对于Linux的系统调用,做到知其然,知其所以然。
    读者对象根据本书的内容,我觉得适合以下几类读者:
    在Linux应用层方面有一定开发经验的程序员。
    对Linux内核有兴趣的程序员。
    热爱Linux内核和开源项目的技术人员。
    如何阅读本书本书定位为APUE的补充或进阶读物,所以假设读者已具备了一定的编程基础,对Linux环境也有所了解,因此在涉及一些基本概念和知识时,只是蜻蜓点水,简单略过。因为笔者希望把更多的笔墨放在更为重要的部分,而不是各种相关图书均有讲解的基本概念上。所以如果你是初学者,建议还是先学习APUE、C语言编程,并且在具有一定的操作系统知识后再来阅读本书。
    Linux环境编程涉及的领域太多,很难有某个人可以在Linux的各个领域均有比较深刻的认识,尤其是已有APUE这本经典图书在前,所以本书是由高峰、李彬两个人共同完成的。
    高峰负责第0、1、2、3、4、12、13、14、15章,李彬负责第5~11章。两位不同的作者,在写作风格上很难保证一致,如果给各位读者带来了不便,在此给各位先道个歉。尽管是由两个人共同写作,并且负责的还是我们各自相对擅长的领域,可是在写作的过程中我们仍然感觉到很吃力,用了将近三年的时间才算完成本书。对比APUE,本书一方面在深度上还是有所不及,另一方面在广度上还是没有涵盖APUE涉及的所有领域,这也让我们对Stevens大师更加敬佩。
    本书使用的Linux内核源代码版本为3.2.44,glibc的源码版本为2.17。
    勘误和支持由于作者的水平有限,主题又过于宏大,书中难免会出现一些错误或不准确的地方,如有不妥之处,恳请读者批评指正。如果你发现有什么问题,或者有什么疑问,都可以发邮件至我的邮箱gfree.wind@gmail.com,期待您的指导!
    致谢首先要感谢伟大的Linux内核创始人Linus,他开创了一个影响世界的操作系统。
    其次要感谢机械工业出版社华章公司的编辑杨绣国老师(Lisa),感谢你的魄力,敢于找新人来写作,并敢于信任新人,让其完成这么大的一个项目。感谢你的耐心,正常的一年半的写作时间,被我们生生地延长到了将近三年的时间,感谢你在写作过程中对我们的鼓励和帮助。
    然后要感谢我的搭档李彬,在我加入当前的创业公司后,只有很少的空闲时间和精力来投入写作。这时,是李彬在更紧张的时间内,承担了本书的一半内容。并且其写作态度极其认真,对质量精益求精。没有李彬的加入,本书很可能就半途而废了。再次感谢李彬,我的好搭档。
    最后我要感谢我的亲人。感谢我的父母,没有你们的培养,绝没有我的今天;感谢我的妻子,没有你的支持,就没有我事业上的进步;感谢我的岳父岳母对我女儿的照顾,使我没有后顾之忧;最后要感谢的是我可爱的女儿高一涵小天使,你的诞生为我带来了无尽的欢乐和动力!
    谨以此书,献给我最亲爱的家人,以及众多热爱Linux的朋友们。
    高  峰中国北京2016年3月

蜀ICP备2024047804号

Copyright 版权所有 © jvwen.com 聚文网