上冊
第1章 曆史和標準 1
1.1 unix和c語言簡史 1
1.2 linux簡史 4
1.2.1 gnu項目 4
1.2.2 linux內核 5
1.3 標準化 8
1.3.1 c編程語言 8
1.3.2 首個posix標準 9
1.3.3 x/open公司和the open group 10
1.3.4 susv3和posix.1-2001 10
1.3.5 susv4和posix.1-2008 12
1.3.6 unix標準時間錶 12
1.3.7 實現標準 14
1.3.8 linux、標準、linux標準規範(linux standard base) 14
1.4 總結 15
第2章 基本概念 17
2.1 操作係統的核心—內核 17
2.2 shell 19
.2.3 用戶和組 20
2.4 單根目錄層級、目錄、鏈接及文件 21
2.5 文件i/o模型 23
2.6 程序 24
2.7 進程 25
2.8 內存映射 27
2.9 靜態庫和共享庫 28
2.10 進程間通信及同步 28
2.11 信號 29
2.12 綫程 30
2.13 進程組和shell任務控製 30
2.14 會話、控製終端和控製進程 30
2.15 僞終端 31
2.16 日期和時間 31
2.17 客戶端服務器架構 32
2.18 實時性 32
2.19 /proc文件係統 33
2.20 總結 33
第3章 係統編程概念 34
3.1 係統調用 34
3.2 庫函數 36
3.3 標準c語言函數庫;gnu c語言函數庫(glibc) 37
3.4 處理來自係統調用和庫函數的錯誤 38
3.5 關於本書示例程序的注意事項 40
3.5.1 命令行選項及參數 40
3.5.2 常用的函數及頭文件 40
3.6 可移植性問題 49
3.6.1 特性測試宏 49
3.6.2 係統數據類型 51
3.6.3 其他的可移植性問題 53
3.7 總結 54
3.8 練習 55
第4章 文件i/o:通用的i/o模型 56
4.1 概述 56
4.2 通用i/o 58
4.3 打開一個文件:open() 58
4.3.1 open()調用中的flags參數 60
4.3.2 open()函數的錯誤 63
4.3.3 creat()係統調用 64
4.4 讀取文件內容:read() 64
4.5 數據寫入文件:write() 65
4.6 關閉文件:close() 66
4.7 改變文件偏移量:lseek() 66
4.8 通用i/o模型以外的操作:ioctl() 70
4.9 總結 71
4.10 練習 71
第5章 深入探究文件i/o 72
5.1 原子操作和競爭條件 72
5.2 文件控製操作:fcntl() 75
5.3 打開文件的狀態標誌 75
5.4 文件描述符和打開文件之間的關係 76
5.5 復製文件描述符 78
5.6 在文件特定偏移量處的i/o:pread()和pwrite() 80
5.7 分散輸入和集中輸齣(scatter-gather i/o):readv()和writev() 81
5.8 截斷文件:truncate()和ftruncate()係統調用 84
5.9 非阻塞i/o 84
5.10 大文件i/o 85
5.11 /dev/fd目錄 88
5.12 創建臨時文件 88
5.13 總結 90
5.14 練習 90
第6章 進程 92
6.1 進程和程序 92
6.2 進程號和父進程號 93
6.3 進程內存布局 94
6.4 虛擬內存管理 97
6.5 棧和棧幀 99
6.6 命令行參數(argc, argv) 99
6.7 環境列錶 101
6.8 執行非局部跳轉:setjmp()和longjmp() 106
6.9 總結 111
6.9 練習 112
第7章 內存分配 113
7.1 在堆上分配內存 113
7.1.1 調整program break:brk()和sbrk() 113
7.1.2 在堆上分配內存:malloc()和free() 114
7.1.3 malloc()和free()的實現 117
7.1.4 在堆上分配內存的其他方法 120
7.2 在堆棧上分配內存:alloca() 122
7.3 總結 123
7.4 練習 123
第8章 用戶和組 124
8.1 密碼文件:/etc/passwd 124
8.2 shadow密碼文件:/etc/shadow 125
8.3 組文件:/etc/group 126
8.4 獲取用戶和組的信息 127
8.5 密碼加密和用戶認證 132
8.6 總結 135
8.7 練習 135
第9章 進程憑證 136
9.1 實際用戶id和實際組id 136
9.2 有效用戶id和有效組id 136
9.3 set-user-id和set-group-id程序 137
9.4 保存set-user-id和保存set-group-id 138
9.5 文件係統用戶id和組id 139
9.6 輔助組id 140
9.7 獲取和修改進程憑證 140
9.7.1 獲取和修改實際、有效和保存設置標識 140
9.7.2 獲取和修改文件係統id 145
9.7.3 獲取和修改輔助組id 145
9.7.4 修改進程憑證的係統調用總結 146
9.7.5 示例:顯示進程憑證 148
9.8 總結 149
9.9 習題 150
第10章 時間 151
10.1 日曆時間(calendar time) 151
10.2 時間轉換函數 153
10.2.1 將time_t轉換為可打印格式 153
10.2.2 time_t和分解時間之間的轉換 154
10.2.3 分解時間和打印格式之間的轉換 155
10.3 時區 161
10.4 地區(locale) 163
10.5 更新係統時鍾 167
10.6 軟件時鍾(jiffies) 168
10.7 進程時間 168
10.8 總結 171
10.9 練習 172
第11章 係統限製和選項 173
11.1 係統限製 174
11.2 在運行時獲取係統限製(和選項) 176
11.3 運行時獲取與文件相關的限製(和選項) 178
11.4 不確定的限製 179
11.5 係統選項 180
11.6 總結 181
11.7 練習 182
第12章 係統和進程信息 183
12.1 /proc文件係統 183
12.1.1 獲取與進程有關的信息:/proc/pid 183
12.1.2 /proc 目錄下的係統信息 185
12.1.3 訪問/proc文件 186
12.2 係統標識:uname() 188
12.3 總結 190
12.4 練習 190
第13章 文件i/o緩衝 191
13.1 文件i/o的內核緩衝:緩衝區高速緩存 191
13.2 stdio庫的緩衝 194
13.3 控製文件i/o的內核緩衝 196
13.4 i/o緩衝小結 200
13.5 就i/o模式嚮內核提齣建議 201
13.6 繞過緩衝區高速緩存:直接i/o 202
13.7 混閤使用庫函數和係統調用進行文件i/o 204
13.8 總結 205
13.9 練習 205
第14章 係統編程概念 207
14.1 設備專用文件(設備文件) 207
14.2 磁盤和分區 208
14.3 文件係統 209
14.4 i節點 211
14.5 虛擬文件係統(vfs) 213
14.6 日誌文件係統 214
14.7 單根目錄層級和掛載點 215
14.8 文件係統的掛載和卸載 216
14.8.1 掛載文件係統:mount() 217
14.8.2 卸載文件係統:umount()和umount2() 222
14.9 高級掛載特性 223
14.9.1 在多個掛載點掛載文件係統 224
14.9.2 多次掛載同一掛載點 224
14.9.3 基於每次掛載的掛載標誌 225
14.9.4 綁定掛載 225
14.9.5 遞歸綁定掛載 226
14.10 虛擬內存文件係統:tmpfs 227
14.11 獲得與文件係統有關的信息:statvfs() 228
14.12 總結 229
14.13 練習 230
第15章 文件屬性 231
15.1 獲取文件信息:stat() 231
15.2 文件時間戳 236
15.2.1 使用utime()和utimes()來改變文件時間戳 238
15.2.2 使用utimensat()和futimens()改變文件時間戳 239
15.3 文件屬主 241
15.3.1 新建文件的屬主 241
15.3.2 改變文件屬主:chown()、fchown()和lchown() 241
15.4 文件權限 244
15.4.1 普通文件的權限 244
15.4.2 目錄權限 246
15.4.3 權限檢查算法 246
15.4.4 檢查對文件的訪問權限:access() 248
15.4.5 set-user-id、set-group-id和sticky位 249
15.4.6 進程的文件模式創建掩碼:umask() 249
15.4.7 更改文件權限:chmod()和fchmod() 251
15.5 i節點標誌(ext2擴展文件屬性) 252
15.6 總結 256
15.7 練習 256
第16章 擴展屬性 258
16.1 概述 258
16.2 擴展屬性的實現細節 260
16.3 操控擴展屬性的係統調用 260
16.4 總結 264
16.5 練習 264
第17章 訪問控製列錶 265
17.1 概述 265
17.2 acl權限檢查算法 267
17.3 acl的長、短文本格式 268
17.4 acl_mask型ace和acl組分類 269
17.5 getfacl和setfacl命令 270
17.6 默認acl與文件創建 271
17.7 acl在實現方麵的限製 272
17.8 acl api 273
17.9 總結 280
17.10 練習 280
第18章 目錄與鏈接 281
18.1 目錄和(硬)鏈接 281
18.2 符號(軟)鏈接 283
18.3 創建和移除(硬)鏈接:link()和 unlink() 286
18.4 更改文件名:rename() 289
18.5 使用符號鏈接:symlink()和readlink() 290
18.6 創建和移除目錄:mkdir()和rmdir() 291
18.7 移除一個文件或目錄:remove() 292
18.8 讀目錄:opendir()和readdir() 292
18.9 文件樹遍曆:nftw() 297
18.10 進程的當前工作目錄 301
18.11 針對目錄文件描述符的相關操作 303
18.12 改變進程的根目錄:chroot() 304
18.13 解析路徑名:realpath() 306
18.14 解析路徑名字符串:dirname()和basename() 307
18.15 總結 309
18.16 練習 309
第19章 監控文件事件 311
19.1 概述 311
19.2 inotify api 312
19.3 inotify事件 313
19.4 讀取inotify事件 315
19.5 隊列限製和/proc文件 319
19.6 監控文件的舊有係統:dnotify 320
19.7 總結 320
19.8 練習 320
第20章 信號:基本概念 321
20.1 概念和概述 321
20.2 信號類型和默認行為 323
20.3 改變信號處置:signal() 329
20.4 信號處理器簡介 330
20.5 發送信號:kill() 333
20.6 檢查進程的存在 334
20.7 發送信號的其他方式:raise()和killpg() 335
20.8 顯示信號描述 336
20.9 信號集 337
20.10 信號掩碼(阻塞信號傳遞) 339
20.11 處於等待狀態的信號 341
20.12 不對信號進行排隊處理 341
20.13 改變信號處置:sigaction () 345
20.14 等待信號:pause() 346
20.15 總結 347
20.16 練習 347
第21章 信號:信號處理器函數 348
21.1 設計信號處理器函數 348
21.1.1 再論信號的非隊列化處理 348
21.1.2 可重入函數和異步信號安全函數 349
21.1.3 全局變量和sig_atomic_t數據類型 353
21.2 終止信號處理器函數的其他方法 354
21.2.1 在信號處理器函數中執行非本地跳轉 354
21.2.2 異常終止進程:abort() 358
21.3 在備選棧中處理信號:sigaltstack() 358
21.4 sa_siginfo標誌 361
21.5 係統調用的中斷和重啓 366
21.6 總結 368
21.7 練習 369
第22章 信號:高級特性 370
22.1 核心轉儲文件 370
22.2 傳遞、處置及處理的特殊情況 372
22.3 可中斷和不可中斷的進程睡眠狀態 373
22.4 硬件産生的信號 374
22.5 信號的同步生成和異步生成 374
22.6 信號傳遞的時機與順序 375
22.7 signal()的實現及可移植性 376
22.8 實時信號 378
22.8.1 發送實時信號 379
22.8.2 處理實時信號 380
22.9 使用掩碼來等待信號:sigsuspend() 384
22.10 以同步方式等待信號 387
22.11 通過文件描述符來獲取信號 390
22.12 利用信號進行進程間通信 393
22.13 早期的信號api(system v和bsd) 393
22.14 總結 395
22.15 練習 396
第23章 定時器與休眠 397
23.1 間隔定時器 397
23.2 定時器的調度及精度 402
23.3 為阻塞操作設置超時 402
23.4 暫停運行(休眠)一段固定時間 404
23.4.1 低分辨率休眠:sleep() 404
23.4.2 高分辨率休眠:nanosleep() 404
23.5 posix時鍾 407
23.5.1 獲取時鍾的值:clock_gettime() 407
23.5.2 設置時鍾的值:clock_settime() 408
23.5.3 獲取特定進程或綫程的時鍾id 408
23.5.4 高分辨率休眠的改進版:clock_nanosleep() 409
23.6 posix間隔式定時器 410
23.6.1 創建定時器:timer_create() 410
23.6.2 配備和解除定時器:timer_settime() 412
23.6.3 獲取定時器的當前值:timer_gettime() 413
23.6.4 刪除定時器:timer_delete() 413
23.6.5 通過信號發齣通知 414
23.6.6 定時器溢齣 417
23.6.7 通過綫程來通知 417
23.7 利用文件描述符進行通知的定時器:timerfd api 420
23.8 總結 423
23.9 練習 424
第24章 進程的創建 425
24.1 fork()、exit()、wait()以及execve()的簡介 425
24.2 創建新進程:fork() 427
24.2.1 父、子進程間的文件共享 428
24.2.2 fork()的內存語義 430
24.3 係統調用vfork() 433
24.4 fork()之後的競爭條件(race condition) 434
24.5 同步信號以規避競爭條件 436
24.6 總結 438
24.7 練習 439
第25章 進程的終止 440
25.1 進程的終止:_exit()和exit() 440
25.2 進程終止的細節 441
25.3 退齣處理程序 442
25.4 fork()、stdio緩衝區以及_exit()之間的交互 445
25.5 總結 446
25.6 練習 446
第26章 監控子進程 447
26.1 等待子進程 447
26.1.1 係統調用wait() 447
26.1.2 係統調用waitpid() 449
26.1.3 等待狀態值 450
26.1.4 從信號處理程序中終止進程 454
26.1.5 係統調用waitid() 455
26.1.6 係統調用wait3()和wait4() 456
26.2 孤兒進程與僵屍進程 457
26.3 sigchld信號 459
26.3.1 為sigchld建立信號處理程序 459
26.3.2 嚮已停止的子進程發送sigchld信號 462
26.3.3 忽略終止的子進程 462
26.4 總結 464
26.5 練習 464
第27章 程序的執行 465
27.1 執行新程序:execve() 465
27.2 exec()庫函數 468
27.2.1 環境變量path 469
27.2.2 將程序參數指定為列錶 470
27.2.3 將調用者的環境傳遞給新程序 471
27.2.4 執行由文件描述符指代的程序:fexecve() 471
27.3 解釋器腳本 472
27.4 文件描述符與exec() 474
27.5 信號與exec() 477
27.6 執行shell命令:system() 477
27.7 system()的實現 480
27.8 總結 485
27.9 練習 485
第28章 詳述進程創建和程序執行 487
28.1 進程記賬 487
28.2 係統調用clone() 493
28.2.1 clone()的flags參數 497
28.2.2 因剋隆生成的子進程而對waitpid()進行的擴展 503
28.3 進程的創建速度 503
28.4 exec()和fork()對進程屬性的影響 505
28.5 總結 508
28.6 練習 508
第29章 綫程:介紹 509
29.1 概述 509
29.2 pthreads api的詳細背景 511
29.3 創建綫程 513
29.4 終止綫程 514
29.5 綫程id(thread id) 514
29.6 連接(joining)已終止的綫程 515
29.7 綫程的分離 517
29.8 綫程屬性 518
29.9 綫程vs進程 518
29.10 總結 519
29.11 練習 519
第30章 綫程:綫程同步 521
30.1 保護對共享變量的訪問:互斥量 521
30.1.1 靜態分配的互斥量 524
30.1.2 加鎖和解鎖互斥量 524
30.1.3 互斥量的性能 526
30.1.4 互斥量的死鎖 527
30.1.5 動態初始化互斥量 527
30.1.6 互斥量的屬性 528
30.1.7 互斥量類型 528
30.2 通知狀態的改變:條件變量(condition variable) 529
30.2.1 由靜態分配的條件變量 530
30.2.2 通知和等待條件變量 531
30.2.3 測試條件變量的判斷條件(predicate) 534
30.2.4 示例程序:連接任意已終止綫程 534
30.2.5 經由動態分配的條件變量 537
30.3 總結 538
30.4 練習 538
第31章 綫程:綫程安全和每綫程存儲 539
31.1 綫程安全(再論可重入性) 539
31.2 一次性初始化 541
31.3 綫程特有數據 542
31.3.1 庫函數視角下的綫程特有數據 542
31.3.2 綫程特有數據api概述 543
31.3.3 綫程特有數據api詳述 543
31.3.4 使用綫程特有數據api 545
31.3.5 綫程特有數據的實現限製 549
31.4 綫程局部存儲 549
31.5 總結 550
31.6 練習 551
第32章 綫程:綫程取消 552
32.1 取消一個綫程 552
32.2 取消狀態及類型 552
32.3 取消點 553
32.4 綫程可取消性的檢測 556
32.5 清理函數(cleanup handler) 556
32.6 異步取消 559
32.7 總結 560
第33章 綫程:更多細節 561
33.1 綫程棧 561
33.2 綫程和信號 562
33.2.1 unix信號模型如何映射到綫程中 562
33.2.2 操作綫程信號掩碼 563
33.2.3 嚮綫程發送信號 563
33.2.4 妥善處理異步信號 564
33.3 綫程和進程控製 564
33.4 綫程實現模型 566
33.5 linux posix綫程的實現 567
33.5.1 linuxthreads 567
33.5.2 nptl 569
33.5.3 哪一種綫程實現 570
33.6 pthread api的高級特性 572
33.7 總結 572
33.8 練習 572
下冊
第34章 進程組、會話和作業控製 573
34.1 概述 573
34.2 進程組 575
34.3 會話 577
34.4 控製終端和控製進程 578
34.5 前颱和後颱進程組 580
34.6 sighup信號 581
34.6.1 在shell中處理sighup信號 581
34.6.2 sighup和控製進程的終止 583
34.7 作業控製 585
34.7.1 在shell中使用作業控製 585
34.7.2 實現作業控製 587
34.7.3 處理作業控製信號 591
34.7.4 孤兒進程組(sighup迴顧) 594
34.8 總結 598
34.9 習題 599
第35章 進程優先級和調度 600
35.1 進程優先級(nice值) 600
35.2 實時進程調度概述 603
35.2.1 sched_rr策略 604
35.2.2 sched_fifo策略 605
35.2.3 sched_batch和sched_idle策略 605
35.3 實時進程調用api 605
35.3.1 實時優先級範圍 606
35.3.2 修改和獲取策略和優先級 606
35.3.3 釋放cpu 611
35.3.4 sched_rr時間片 611
35.4 cpu親和力 612
35.5 總結 614
35.6 習題 615
第36章 進程資源 617
36.1 進程資源使用 617
36.2 進程資源限製 619
36.3 特定資源限製細節 623
36.4 總結 627
36.5 習題 627
第37章 daemon 628
37.1 概述 628
37.2 創建一個daemon 629
37.3 編寫daemon指南 632
37.4 使用sighup重新初始化一個daemon 632
37.5 使用syslog記錄消息和錯誤 635
37.5.1 概述 635
37.5.2 syslog api 636
37.5.3 /etc/syslog.conf文件 640
37.6 總結 641
37.7 習題 641
第38章 編寫安全的特權程序 642
38.1 是否需要一個set-user-id或set-group-id程序? 642
38.2 以最小權限操作 643
38.3 小心執行程序 645
38.4 避免暴露敏感信息 646
38.5 確定進程的邊界 647
38.6 小心信號和競爭條件 647
38.7 執行文件操作和文件i/o的缺陷 648
38.8 不要完全相信輸入和環境 648
38.9 小心緩衝區溢齣 649
38.10 小心拒絕服務攻擊 650
38.11 檢查返迴狀態和安全地處理失敗情況 651
38.12 總結 651
38.13 習題 652
第39章 能力 653
39.1 能力基本原理 653
39.2 linux能力 654
39.3 進程和文件能力 654
39.3.1 進程能力 654
39.3.2 文件能力 655
39.3.3 進程許可和有效能力集的目的 657
39.3.4 文件許可和有效能力集的目的 657
39.3.5 進程和文件可繼承集的目的 658
39.3.6 在shell中給文件賦予能力和查看文件能力 658
39.4 現代能力實現 659
39.5 在exec()中轉變進程能力 659
39.5.1 能力邊界集 660
39.5.2 保持root語義 660
39.6 改變用戶id對進程能力的影響 661
39.7 用編程的方式改變進程能力 661
39.8 創建僅包含能力的環境 665
39.9 發現程序所需的能力 667
39.10 不具備文件能力的老式內核和係統 667
39.11 總結 669
39.12 習題 669
第40章 登錄記賬 670
40.1 utmp和wtmp文件概述 670
40.2 utmpx api 671
40.3 utmpx結構 671
40.4 從utmp和wtmp文件中檢索信息 673
40.5 獲取登錄名稱:getlogin() 676
40.6 為登錄會話更新utmp和wtmp文件 677
40.7 lastlog文件 681
40.8 總結 683
40.9 習題 683
第41章 共享庫基礎 684
41.1 目標庫 684
41.2 靜態庫 685
41.3 共享庫概述 686
41.4 創建和使用共享庫——首迴閤 687
41.4.1 創建一個共享庫 687
41.4.2 位置獨立的代碼 687
41.4.3 使用一個共享庫 688
41.4.4 共享庫soname 689
41.5 使用共享庫的有用工具 691
41.6 共享庫版本和命名規則 692
41.7 安裝共享庫 694
41.8 兼容與不兼容庫比較 696
41.9 升級共享庫 697
41.10 在目標文件中指定庫搜索目錄 698
41.11 在運行時找齣共享庫 700
41.12 運行時符號解析 700
41.13 使用靜態庫取代共享庫 701
41.14 總結 702
41.15 習題 703
第42章 共享庫高級特性 704
42.1 動態加載庫 704
42.1.1 打開共享庫:dlopen() 705
42.1.2 錯誤診斷:dlerror() 706
42.1.3 獲取符號的地址:dlsym() 707
42.1.4 關閉共享庫:dlclose() 709
42.1.5 獲取與加載的符號相關的信息:dladdr() 710
42.1.6 在主程序中訪問符號 710
42.2 控製符號的可見性 710
42.3 鏈接器版本腳本 711
42.3.1 使用版本腳本控製符號的可見性 712
42.3.2 符號版本化 713
42.4 初始化和終止函數 715
42.5 預加載共享庫 716
42.6 監控動態鏈接器:ld_debug 716
42.7 總結 717
42.8 習題 718
第43章 進程間通信簡介 719
43.1 ipc工具分類 719
43.2 通信工具 720
43.3 同步工具 721
43.4 ipc工具比較 723
43.5 總結 727
43.6 習題 727
第44章 管道和fifo 728
44.1 概述 728
44.2 創建和使用管道 730
44.3 將管道作為一種進程同步的方法 735
44.4 使用管道連接過濾器 737
44.5 通過管道與shell命令進行通信:popen() 739
44.6 管道和stdio緩衝 743
44.7 fifo 743
44.8 使用管道實現一個客戶端/服務器應用程序 745
44.9 非阻塞i/o 751
44.10 管道和fifo中read()和write()的語義 752
44.11 總結 753
44.12 習題 754
第45章 system v ipc介紹 756
45.1 概述 757
45.2 ipc key 759
45.3 關聯數據結構和對象權限 761
45.4 ipc標識符和客戶端/服務器應用程序 763
45.5 system v ipc get調用使用的算法 764
45.6 ipcs和ipcrm命令 766
45.7 獲取所有ipc對象列錶 767
45.8 ipc限製 767
45.9 總結 768
45.10 習題 768
第46章 system v消息隊列 769
46.1 創建或打開一個消息隊列 769
46.2 交換消息 771
46.2.1 發送消息 772
46.2.2 接收消息 774
46.3 消息隊列控製操作 777
46.4 消息隊列關聯數據結構 778
46.5 消息隊列的限製 780
46.6 顯示係統中所有消息隊列 781
46.7 使用消息隊列實現客戶端/服務器應用程序 783
46.8 使用消息隊列實現文件服務器應用程序 784
46.9 system v消息隊列的缺點 790
46.10 總結 790
46.11 習題 791
第47章 system v信號量 792
47.1 概述 793
47.2 創建或打開一個信號量集 795
47.3 信號量控製操作 796
47.4 信號量關聯數據結構 798
47.5 信號量初始化 801
47.6 信號量操作 803
47.7 多個阻塞信號量操作的處理 809
47.8 信號量撤銷值 810
47.9 實現一個二元信號量協議 811
47.10 信號量限製 814
47.11 system v信號量的缺點 815
47.12 總結 816
47.13 習題 817
第48章 system v共享內存 818
48.1 概述 818
48.2 創建或打開一個共享內存段 819
48.3 使用共享內存 820
48.4 示例:通過共享內存傳輸數據 821
48.5 共享內存在虛擬內存中的位置 825
48.6 在共享內存中存儲指針 828
48.7 共享內存控製操作 829
48.8 共享內存關聯數據結構 830
48.9 共享內存的限製 832
48.10 總結 833
48.11 習題 833
第49章 內存映射 835
49.1 概述 835
49.2 創建一個映射:mmap() 837
49.3 解除映射區域:munmap() 840
49.4 文件映射 840
49.4.1 私有文件映射 841
49.4.2 共享文件映射 842
49.4.3 邊界情況 845
49.4.4 內存保護和文件訪問模式交互 846
49.5 同步映射區域:msync() 847
49.6 其他mmap()標記 848
49.7 匿名映射 849
49.8 重新映射一個映射區域:mremap() 852
49.9 map_noreserve和過度利用交換空間 853
49.10 map_fixed標記 854
49.11 非綫性映射:remap_file_pages() 855
49.12 總結 857
49.13 習題 858
第50章 虛擬內存操作 859
50.1 改變內存保護:mprotect() 859
50.2 內存鎖:mlock()和mlockatt() 861
50.3 確定內存駐留性:mincore() 864
50.4 建議後續的內存使用模式:madvise() 866
50.5 小結 868
50.6 習題 868
第51章 posix ipc介紹 869
51.1 api概述 869
51.2 system v ipc與posix ipc比較 872
51.3 總結 873
第52章 posix消息隊列 874
52.1 概述 874
52.2 打開、關閉和斷開鏈接消息隊列 875
52.3 描述符和消息隊列之間的關係 877
52.4 消息隊列特性 878
52.5 交換消息 882
52.5.1 發送消息 882
52.5.2 接收消息 883
52.5.3 在發送和接收消息時設置超時時間 885
52.6 消息通知 886
52.6.1 通過信號接收通知 887
52.6.2 通過綫程接收通知 889
52.7 linux特有的特性 891
52.8 消息隊列限製 892
52.9 posix和system v消息隊列比較 893
52.10 總結 894
52.11 習題 894
第53章 posix信號量 895
53.1 概述 895
53.2 命名信號量 895
53.2.1 打開一個命名信號量 896
53.2.2 關閉一個信號量 898
53.2.3 刪除一個命名信號量 898
53.3 信號量操作 899
53.3.1 等待一個信號量 899
53.3.2 發布一個信號量 901
53.3.3 獲取信號量的當前值 901
53.4 未命名信號量 903
53.4.1 初始化一個未命名信號量 904
53.4.2 銷毀一個未命名信號量 906
53.5 與其他同步技術比較 906
53.6 信號量的限製 907
53.7 總結 908
53.8 習題 908
第54章 posix共享內存 909
54.1 概述 909
54.2 創建共享內存對象 910
54.3 使用共享內存對象 913
54.4 刪除共享內存對象 915
54.5 共享內存apis比較 915
54.6 總結 916
54.7 習題 917
第55章 文件加鎖 918
55.1 概述 918
55.2 使用flock()給文件加鎖 920
55.2.1 鎖繼承與釋放的語義 922
55.2.2 flock()的限製 923
55.3 使用fcntl()給記錄加鎖 923
55.3.1 死鎖 928
55.3.2 示例:一個交互式加鎖程序 928
55.3.3 示例:一個加鎖函數庫 931
55.3.4 鎖的限製和性能 933
55.3.5 鎖繼承和釋放的語義 934
55.3.6 鎖定餓死和排隊加鎖請求的優先級 935
55.4 強製加鎖 935
55.5 /proc/locks文件 938
55.6 僅運行一個程序的單個實例 939
55.7 老式加鎖技術 941
55.8 總結 942
55.9 習題 943
第56章 socket:介紹 945
56.1 概述 945
56.2 創建一個socket:socket() 948
56.3 將socket綁定到地址:bind() 948
56.4 通用socket地址結構:struct sockaddr 949
56.5 流socket 950
56.5.1 監聽接入連接:listen() 951
56.5.2 接受連接:accept() 952
56.5.3 連接到對等socket:connect() 952
56.5.4 流socket i/o 953
56.5.5 連接終止:close() 953
56.6 數據報socket 953
56.6.1 交換數據報:recvfrom和sendto() 954
56.6.2 在數據報socket上使用connect() 955
56.7 總結 956
第57章 socket:unix domain 957
57.1 unix domain socket地址:struct sockaddr_un 957
57.2 unix domain中的流socket 959
57.3 unix domain中的數據報socket 962
57.4 unix domain socket權限 965
57.5 創建互聯socket對:socketpair() 965
57.6 linux抽象socket名空間 966
57.7 總結 967
57.8 習題 967
第58章 socket:tcp/ip網絡基礎 968
58.1 因特網 968
58.2 聯網協議和層 969
58.3 數據鏈路層 971
58.4 網絡層:ip 971
58.5 ip地址 973
58.6 傳輸層 975
58.6.1 端口號 975
58.6.2 用戶數據報協議(udp) 976
58.6.3 傳輸控製協議(tcp) 977
58.7 請求注解(rfc) 979
58.8 總結 980
第59章 socket:internet domain 982
59.1 internet domain socket 982
59.2 網絡字節序 982
59.3 數據錶示 984
59.4 internet socket地址 986
59.5 主機和服務轉換函數概述 988
59.6 inet_pton()和inet_ntop()函數 989
59.7 客戶端-服務器示例(數據報socket) 990
59.8 域名係統(dns) 992
59.9 /etc/services文件 994
59.10 獨立於協議的主機和服務轉換 995
59.10.1 getaddrinfo()函數 996
59.10.2 釋放addrinfo列錶:freeaddrinfo() 998
59.10.3 錯誤診斷:gai_strerror() 999
59.10.4 getnameinfo()函數 999
59.11 客戶端-服務器示例(流式socket) 1000
59.12 internet domain socket庫 1006
59.13 過時的主機和服務轉換api 1010
59.13.1 inet_aton()和inet_ntoa()函數 1010
59.13.2 gethostbyname()和gethostbyaddr()函數 1010
59.13.3 getserverbyname()和getserverbyport()函數 1012
59.14 unix與internet domain socket比較 1013
59.15 更多信息 1014
59.16 總結 1014
59.17 習題 1015
第60章 socket:服務器設計 1016
60.1 迭代型和並發型服務器 1016
60.2 迭代型udp echo服務器 1016
60.3 並發型tcp echo服務器 1019
60.4 並發型服務器的其他設計方案 1021
60.5 inetd(internet超級服務器)守護進程 1023
60.6 總結 1027
60.7 練習 1027
第61章 socket:高級主題 1028
61.1 流式套接字上的部分讀和部分寫 1028
61.2 shutdown()係統調用 1030
61.3 專用於套接字的i/o係統調用:recv()和send() 1033
61.4 sendfile()係統調用 1034
61.5 獲取套接字地址 1036
61.6 深入探討tcp協議 1039
61.6.1 tcp報文的格式 1039
61.6.2 tcp序列號和確認機製 1041
61.6.3 tcp協議狀態機以及狀態遷移圖 1041
61.6.4 tcp連接的建立 1043
61.6.5 tcp連接的終止 1044
61.6.6 在tcp套接字上調用shutdown() 1045
61.6.7 time_wait狀態 1045
61.7 監視套接字:netstat 1047
61.8 使用tcpdump來監視tcp流量 1048
61.9 套接字選項 1049
61.10 so_reuseaddr套接字選項 1050
61.11 在accept()中繼承標記和選項 1051
61.12 tcp vs udp 1052
61.13 高級功能 1053
61.13.1 帶外數據 1053
61.13.2 sendmsg()和recvmsg()係統調用 1053
61.13.3 傳遞文件描述符 1054
61.13.4 接收發送端的憑據 1054
61.13.5 順序數據包套接字 1055
61.13.6 sctp以及dccp傳輸層協議 1055
61.14 總結 1056
61.15 練習 1056
第62章 終端 1058
62.1 整體概覽 1059
62.2 獲取和修改終端屬性 1060
62.3 stty命令 1062
62.4 終端特殊字符 1063
62.5 終端標誌 1068
62.6 終端的i/o模式 1073
62.6.1 規範模式 1073
62.6.2 非規範模式 1074
62.6.3 加工模式、cbreak模式以及原始模式 1075
62.7 終端綫速(比特率) 1081
62.8 終端的行控製 1082
62.9 終端窗口大小 1084
62.10 終端標識 1085
62.11 總結 1086
62.12 練習 1087
第63章 其他備選的i/o模型 1088
63.1 整體概覽 1088
63.1.1 水平觸發和邊緣觸發 1091
63.1.2 在備選的i/o模型中采用非阻塞i/o 1092
63.2 i/o多路復用 1092
63.2.1 select()係統調用 1092
63.2.2 poll()係統調用 1097
63.2.3 文件描述符何時就緒? 1101
63.2.4 比較select()和poll() 1103
63.2.5 select()和poll()存在的問題 1105
63.3 信號驅動i/o 1105
63.3.1 何時發送“i/o就緒”信號 1109
63.3.2 優化信號驅動i/o的使用 1110
63.4 epoll編程接口 1113
63.4.1 創建epoll實例:epoll_create() 1113
63.4.2 修改epoll的興趣列錶:epoll_ctl() 1114
63.4.3 事件等待:epoll_wait() 1115
63.4.4 深入探究epoll的語義 1120
63.4.5 epoll同i/o多路復用的性能對比 1121
63.4.6 邊緣觸發通知 1122
63.5 在信號和文件描述符上等待 1124
63.5.1 pselect()係統調用 1125
63.5.2 self-pipe技巧 1126
63.6 總結 1128
63.7 練習 1129
第64章 僞終端 1130
64.1 整體概覽 1130
64.2 unix98僞終端 1133
64.2.1 打開未使用的主設備:posix_openpt() 1134
64.2.2 修改從設備屬主和權限:grantpt() 1135
64.2.3 解鎖從設備:unlockpt() 1135
64.2.4 獲取從設備名稱:ptsname() 1136
64.3 打開主設備:ptymasteropen() 1136
64.4 將進程連接到僞終端:ptyfork() 1138
64.5 僞終端i/o 1140
64.6 實現script(1)程序 1142
64.7 終端屬性和窗口大小 1146
64.8 bsd風格的僞終端 1146
64.9 總結 1148
64.10 練習 1149
附錄a 跟蹤係統調用 1151
附錄b 解析命令行選項 1153
附錄c 對null指針做轉型 1159
附錄d 內核配置 1161
附錄e 更多信息源 1162
附錄f 部分習題解答 1167
· · · · · · (
收起)