第1章 Unix系統(tǒng)編程概述
1.1 介紹
1.2 什么是系統(tǒng)編程
1.2.1 簡單的程序模型
1.2.2 系統(tǒng)模型
1.2.3 操作系統(tǒng)的職責
1.2.4 為程序提供服務
1.3 理解系統(tǒng)編程
1.3.1 系統(tǒng)資源
1.3.2 目標:理解系統(tǒng)編程
1.3.3 方法:通過三個問題來理解
1.4 從用戶的角度來理解Unix
1.4.1 Unix能做些什么
1.4.2 登錄--運行程序--注銷
1.4.3 目錄操作
1.4.4 文件操作
1.5 從系統(tǒng)的角度來看Unix
1.5.1 用戶和程序之間的連接方式
1.5.2 網絡橋牌
1.5.3 bc:Unix的計算器
1.5.4 從bc/dc到Web
1.6 動手實踐
1.7 工作步驟與概要圖
1.7.1 接下來的工作步驟
1.7.2 Unix的概要圖
1.7.3 Unix的發(fā)展歷程
小結
第2章 用戶、文件操作與聯機幫助:編寫who命令
2.1 介紹
2.2 關于命令who
2.3 問題1:who命令能做些什么
2.4 問題2:who命令是如何工作的
2.5 問題3:如何編寫who
2.5.1 問題:如何從文件中讀取數據結構
2.5.2 答案:使用open、read和close
2.5.3 編寫wh01.c
2.5.4 顯示登錄信息
2.5.5 編寫wh02.c
2.5.6 回顧與展望
2.6 編寫cp(讀和寫)
2.6.1 問題1:cp命令能做些什么
2.6.2 問題2:cp命令是如何創(chuàng)建/重寫文件的
2.6.3 問題3:如何編寫cp
2.6.4 Unix編程看起來好像很簡單
2.7 提高文件I/O效率的方法:使用緩沖
2.7.1 緩沖區(qū)的大小對性能的影響
2.7.2 為什么系統(tǒng)調用需要很多時間
2.7.3 低效率的wh02.c
2.7.4 在wh02.c中運用緩沖技術
2.8 內核緩沖技術
2.9 文件讀寫
2.9.1 注銷過程:做了些什么
2.9.2 注銷過程:如何工作的
2.9.3 改變文件的當前位置
2.9.4 編寫終端注銷的代碼
2.10 處理系統(tǒng)調用中的錯誤
小結
第3章 目錄與文件屬性:編寫ls
3.1 介紹
3.2 問題1:1s命令能做什么
3.2.1 1s可以列出文件名和文件的屬性
3.2.2 列出指定目錄或文件的信息
3.2.3 經常用到的命令行選項
3.2.4 問題1的答案
3.3 文件樹
3.4 問題2:1s是如何工作的
3.4.1 什么是目錄
3.4.2 是否可以用open、read和close來操作目錄
3.4.3 如何讀目錄的內容
3.5 問題3:如何編寫ls
3.6 編寫ls-1
3.6.1 問題1:ls-1能做些什么
3.6.2 問題2:ls-1是如何工作的
3.6.3 用stat得到文件信息
3.6.4 stat提供的其他信息
3.6.5 如何實現
3.6.6 將模式字段轉換成字符
3.6.7 將用戶/組ID轉換成字符串
3.6.8 編寫ls2.c
3.7 三個特殊的位
3.7.1 set-user-ID位
3.7.2 set-group-ID位
3.7.3 sticky位
3.7.4 用ls-1看到的特殊屬性
3.8 ls小結
3.9 設置和修改文件的屬性
3.9.1 文件類型
3.9.2 許可位與特殊屬性位
3.9.3 文件的鏈接數
3.9.4 文件所有者與組
3.9.5 文件大小
3.9.6 時間
3.9.7 文件名
小結
第4章 文件系統(tǒng):編寫pwd
4.1 介紹
4.2 從用戶的角度看文件系統(tǒng)
4.2.1 目錄和文件
4.2.2 目錄命令
4.2.3 文件操作命令
4.2.4 針對目錄樹的命令
4.2.5 目錄樹的深度幾乎沒有限制
4.2.6 Unix文件系統(tǒng)小結
4.3 Unix文件系統(tǒng)的內部結構
4.3.1 第一層抽象:從磁盤到分區(qū)
4.3.2 第二層抽象:從磁盤到塊序列
4.3.3 第三層抽象:從塊序列到三個區(qū)域的劃分
4.3.4 文件系統(tǒng)的實現:創(chuàng)建一個文件的過程
4.3.5 文件系統(tǒng)的實現:目錄的工作過程
4.3.6 文件系統(tǒng)的實現:cat命令的工作原理
4.3.7 i-節(jié)點和大文件
4.3.8 Unix文件系統(tǒng)的改進
4.4 理解目錄
4.4.1 理解目錄結構
4.4.2 與目錄樹相關的命令和系統(tǒng)調用
4.5 編寫pwd
4.5.1 pwd的工作過程
4.5.2 pwd的一種版本
4.6 多個文件系統(tǒng)的組合:由多棵樹構成的樹
4.6.1 裝載點
4.6.2 多重i-節(jié)點號和設備交叉鏈接
4.6.3 符號鏈接
小結
第5章 連接控制:學習stty
5.1 為設備編程
5.2 設備就像文件
5.2.1 設備具有文件名
5.2.2 設備和系統(tǒng)調用
5.2.3 例子:終端就像文件
5.2.4 設備文件的屬性
5.2.5 編寫write程序
5.2.6 設備文件和i-節(jié)點
5.3 設備與文件的不同之處
5.4 磁盤連接的屬性
5.4.1 屬性1:緩沖
5.4.2 屬性2:自動添加模式
5.4.3 用open控制文件描述符
5.4.4 磁盤連接小結
5.5 終端連接的屬性
5.5.1 終端的I/O并不如此簡單
5.5.2 終端驅動程序
5.5.3 stty命令
5.5.4 編寫終端驅動程序:關于設置
5.5.5 編寫終端驅動程序:關TX數
5.5.6 編寫終端驅動程序:關于位
5.5.7 編寫終端驅動程序:幾個程序例子
5.5.8 終端連接小結
5.6 其他設備編程:ioctl
5.7 文件、設備和流
小結
第6章 為用戶編程:終端控制和信號
6.1 軟件工具與針對特定設備編寫的程序
6.2 終端驅動程序的模式
6.2.1 規(guī)范模式:緩沖和編輯
6.2.2 非規(guī)范處理
6.2.3 終端模式小結
6.3 編寫一個用戶程序:play_again.c
6.4 信號
6.4.1 Ctrl-C做什么
6.4.2 信號是什么
6.4.3 進程該如何處理信號
6.4.4 信號處理的例子
6.5 為處理信號做準備:play_again4.c
6.6 進程終止
6.7 為設備編程
小結
第7章 事件驅動編程:編寫一個視頻游戲
7.1 視頻游戲和操作系統(tǒng)
7.2 任務:單人彈球游戲(Pong)
7.3 屏幕編程:curses庫
7.3.1 介紹curses
7.3.2 curses內部:虛擬和實際屏幕
7.4 時間編程:sleep
7.5 時鐘編程1:Alarms
7.5.1 添加時延:sleep
7.5.2 sleep()是如何工作的:使用Unix中的Alarms
7.5.3 調度將要發(fā)生的動作
7.6 時間編程2:間隔計時器
7.6.1 添加精度更高的時延:usleep
7.6.2 三種計時器:真實、進程和實用
7.6.3 兩種間隔:初始和重復
7.6.4 用間隔計時器編程
7.6.5 計算機有幾個時鐘
7.6.6 計時器小結
7.7 信號處理1:使用signal
7.7.1 早期的信號處理機制
7.7.2 處理多個信號
7.7.3 測試多個信號
7.7.4 信號機制其他的弱點
7.8 信號處理2:sigaction
7.8.1 處理多個信號:sigaction
7.8.2 信號小結
7.9 防止數據損毀(DataCorruption)
7.9.1 數據損毀的例子
7.9.2 臨界(CriticalSections)
7.9.3 阻塞信號:sigprocmask和sigsetops
7.9.4 重入代碼(ReentrantCode):遞歸調用的危險
7.9.5 視頻游戲中的臨界區(qū)
7.10 kill:從另--個進程發(fā)送的信號
7.11 使用計時器和信號:視頻游戲
7.11.1 bounceld.c:在一條線上控制動畫
7.11.2 bounce2d.c:兩維動畫
7.11.3 完成游戲
7.12 輸入信號,異步I/O
7.12.1 使用異步I/O
7.12.2 方法1:使用OASYNC
7.12.3 方法2:使用aio..read
7.12.4 彈球程序中需要異步讀人嗎
7.12.5 異步輸入、視頻游戲和操作系統(tǒng)
小結
第8章 進程和程序:編寫命令解釋器sh
8.1 進程=運行中的程序
8.2 通過命令ps學習進程
8.2.1 系統(tǒng)進程
8.2.2 進程管理和文件管理
8.2.3 內存和程序
8.3 shell:進程控制和程序控制的--個工具
8.4 shell是如何運行程序的
8.4.1 shell的主循環(huán)
8.4.2 問題1:一個程序如何運行另一個程序
8.4.3 問題2:女口何建立新的進程
8.4.4 問題3:父進程如何等待子進程的退出
8.4.5 小結:shell如何運行程序
8.5 實現一個shell:psh2.c
8.6 思考:用進程編程
8.7 exit和exec的其他細節(jié)
8.7.1 進程死亡:exit和_exit
8.7.2 exec家族
小結
第9章 可編程的shell、shell變量和環(huán)境:編寫自己的shell
9.1 shell編程
9.2 什么是以及為什么要使用shell腳本語言
9.3 smshl--命令行解析
9.4 shell中的流程控制
9.4.1 IF語句做些什么
9.4.2 IF是女口何工作的
9.4.3 在stash中增加IF
9.4.4 smsh2.c:修改后的代碼
9.5 shell變量:局部和全局
9.5.1 使用shell變量
9.5.2 變量的存儲
9.5.3 增加變量命令:Built-ins
9.5.4 效果如何
9.6 環(huán)境:個性化設置
9.6.1 使用環(huán)境
9.6.2 什么是環(huán)境以及它是如何工作的
9.6.3 在smsh中增加環(huán)境處理
9.6.4 varlib.c的代碼
9.7 已實現的shell的功能
小結
第10章 I/O重定向和管道
10.1 shell編程
10.2 一個shell應用程序:監(jiān)視系統(tǒng)用戶
10.3 標準I/O與重定向的若干概念
10.3.1 概念1:3個標準文件描述符
10.3.2 默認的連接:tty
10.3.3 程序都輸出到stdout
10.3.4 重定向I/O的是shell而不是程序
10.3.5 理解I/O重定向
10.3.6 概念2:“最低可用文件描述符(Lowest-Available-fd)”原則
10.3.7 兩個概念的結合
10.4 如何將stdin定向到文件
10.4.1 方法1:closethenopen
10.4.2 方法2:open..close..dup..close
10.4.3 系統(tǒng)調用dup小結
10.4.4 方法3:open..dup2..close
10.4.5 shell為其他程序重定向stdin
10.5 為其他程序重定向I/O:who>userlist
10.6 管道編程
10.6.1 創(chuàng)建管道
10.6.2 使用fork來共享管道
10.6.3 使用pipe、fork以及exec
10.6.4 技術細節(jié):管道并非文件
小結
第11章 連接到近端或遠端的進程:服務器與Socket(套接宇)
11.1 產品和服務
11.2 一個簡單的比喻:飲料機接口
11.3 bc:Unix中使用的計算器
11.3.1 編寫bc:pipe、fork、dup、exec
11.3.2 對協同進程的討論
11.3.3 fdopen:讓文件描述符像文件--樣使用
11.4 popen-讓進程看似文件
11.4.1 popen的功能
11.4.2 實現popen:使用fdopen命令
11.4.3 訪問數據:文件、應用程序接El(APl)和服務器
11.5 socket:與遠端進程相連
11.5.1 類比:“電話中傳來聲音:現在時間是…”
11.5.2 因特網時間、DAP和天氣服務器
11.5.3 服務列表:眾所周知的端口
11.5.4 編寫timeserv.cc時間服務器
11.5.5 測試timeserv.c
11.5.6 編寫timecInt.c:時間服務客戶端
11.5.7 測試timecInt.c
11.5.8 另一種服務器:遠程的ls
11.6 軟件精靈
小結
第12章 連接和協議:編寫Web服務器
12.1 服務器設計重點
12.2 三個主要操作
12.3 操作1和操作2:建立連接
12.3.1 操作1:建立服務器端socket
12.3.2 操作2:建立到服務器的連接
12.3.3 socklib.c
12.4 操作3:客戶/服器的會話
12.4.1 使用socklib.c的timeserv/timecInt
12.4.2 第2版的服務器:使用fork
12.4.3 服務器的設計問題:DIY或代理
12.5 編寫Web服務器
12.5.1 Web服務器功能
12.5.2 設計Web服務器
12.5.3 Web服務器協議
12.5.4 編寫Web服務器
12.5.5 運行Web服務器
12.5.6 Webserv的源程序
12.5.7 比較Web服務器
小結
第13章 基于數據報(Datagram)的編程:編寫許可證服務器
13.1 軟件控制
13.2 許可證控制簡史
13.3 一個非計算機系統(tǒng)實例:轎車管理系統(tǒng)
13.3.1 轎車鑰匙管理描述
13.3.2 用客戶/服務器方式管理轎車
13.4 許可證管理
13.4.1 許可證服務系統(tǒng):它做些什么
13.4.2 許可證服務系統(tǒng):如何工作
13.4.3 一個通信系統(tǒng)的例子
13.5 數據報socket
13.5.1 流與數據報的比較
13.5.2 數據報編程
13.5.3 sendto和recvfrom的小結
13.5.4 數據報應答
13.5.5 數據報小結
13.6 許可證服務器版本1.0
13.6.1 客戶端版本1
13.6.2 服務器端版本1
13.6.3 測試版本1
13.6.4 進一步的工作
13.7 處理現實的問題
13.7.1 處理客戶端崩潰
13.7.2 處理服務器崩潰
13.7.3 測試版本2
13.8 分布式許可證服務器
13.9 Unix域socket
13.9.1 文件名作為socket地址
13.9.2 使用Unix域socket編程
13.10 小結;socket和服務器
小結
第14章 線程機制:并發(fā)函數的使用
14.1 同一時刻完成多項任務
14.2 函數的執(zhí)行路線
14.2.1 一個單線程程序
14.2.2 一個多線程程序
14.2.3 相關函數小結
14.3 線程間的分工合作
14.3.1 例1:incrprint.c
14.3.2 例2:twordcount.c
14.3.3 線程內部的分工合作:小結
14.4 線程與進程
14.5 線程間互通消息
14.5.1 通知選舉中心
14.5.2 使用條件變量編寫程序
14.5.3 使用條件變量的函數
14.5.4 回到Web服務器的例子
14.6 多線程的Web服務器
14.6.1 Web服務器程序的改進
14.6.2 多線程版本允許一個新的功能
14.6.3 防止僵尸線程(ZombieThreads):獨立線程
14.6.4 Web服務器代碼
14.7 線程和動畫
14.7.1 使用線程的優(yōu)點
14.7.2 多線程版本的bouneeld.c
14.7.3 基于多線程機制的多重動畫:tanimate.c
14.7.4 tanimate.c中的互斥量
14.7.5 屏幕控制線程
小結
第15章 進程間通信(1PC)
15.1 編程方式的選擇
15.2 talk命令:從多個數據源讀取數據
15.2.1 同時從兩個文件描述符讀取數據
15.2.2 select系統(tǒng)調用
15.2.3 select與talk
15.2.4 select與poll
15.3 通信的選擇
15.3.1 一個問題的三種解決方案
15.3.2 通過文件的進程間通信
15.3.3 命名管道
15.3.4 共享內存
15.3.5 各種進程間通信方法的比較
15.4 進程之間的分工合作
15.4.1 文件鎖
15.4.2 信號量(Semaphores)
15.4.3 socket及FIFO與共享的存儲
15.5 打印池
15.5.1 多個寫者、一個讀者
15.5.2 客戶/服務器模型
15.6 縱觀IPC
15.7 連接與游戲
小結