---
# System prepended metadata

title: sp筆記
tags: [sp講義]

---

---
tags: sp講義
---
# sp筆記
# ch01-Linux的安裝與操作
>反正就是一些背景介紹，好無聊的
考試前再看個ppt應該就行

![](https://i.imgur.com/UBhKZZR.png)
Linux市佔率高所以要使用(Andriod也是)
## 伺服器版本vs桌面版
伺服器：文字(為了不容易當機)
桌面版：圖形化介面
## 一些安裝
# ch01-安裝開發環境
繼續安裝
# ch02.1，gcc與gdb，github, man, gcc及優化選項, gdb
## github簡單介紹
https://mropengate.blogspot.com/2015/04/git-github.html

## vi vim

<mark>這個一定要會</mark>
**文字模式編輯器**
**vim**：vi進階版(多了顏色)
**Emacs**：跟vi差不多功能
簡單來說就是用來直接寫程式碼的
醬就不用下載寫完再上傳了
## 文字介面 圖形化介面
![](https://i.imgur.com/cRxNO4b.png)

## linux內建說明書
![](https://i.imgur.com/UfU2UOn.png)


### man
>指令的使用手冊
**man 3 printf**(c用的printf介紹)
3：代表第三本書(共9本)
![](https://i.imgur.com/uOy8rSi.png)
**man 2 fork**
![](https://i.imgur.com/pdByjmE.png)
**man -f**：列出所有的使用手冊
![](https://i.imgur.com/pO4S0d9.png)
告訴你在哪幾本書裡面可以找到


---

## gcc與gdb
### **gcc：編譯**
![](https://i.imgur.com/PqEchz6.png)
-O3容易出錯=>因為可能會幫你把看似沒什麼用的東東處理掉
```
a=3;
b=a;
```
醬a就有可能被弄掉
-Os=>編譯出比較小的執行檔

### 指標錯誤
```
#include <stdio.h>
#include <stdlib.h>

int main(){
    int *p; /*指標未給初始值*/
    int ret;
    ret = scanf("%d", p);
    printf("ret = %d, %d",ret, *p);
}
```
=> gcc pointer.c -g -o pointer
=> gcc ./pointer
<mark>(-o後面放執行檔的名字 -g開啟除錯功能)</mark>
出現Segmentation fault，代表是指標出錯
=> bt
![](https://i.imgur.com/jQAjSA9.png)
>main(#2) 呼叫 #1, #1呼叫#0

=> up
![](https://i.imgur.com/cXElR0T.png)
每up一次會**往下**一層(因為os堆疊是由上往下長)

### **gdb：除錯**
![](https://i.imgur.com/3iUgUEN.png)
<mark>**gdb -tui ./pointer**</mark>
同時呼叫出簡易圖型化界面

# ch02.2 make,gprofile,valgrind,perf
## make
![](https://i.imgur.com/kSDWybB.png)
當發現相依性(時間較新)(這裡是target跟後面兩個.o檔)
=>執行下面一行
簡單來說就是你有重寫某個檔他才會重新編譯這個檔

![](https://i.imgur.com/bJvNXLt.png)
ex：make hello =>執行hello那行

![](https://i.imgur.com/McXk8tX.png)
make後面若沒有跟任何參數的話
就會make all

## gprofile
>GNU C內建的效能衡量工具
(看執行時間之類的)
### 編譯
=> gcc table.c -pg -o table
=> ./table
=> gprof -b table gmon.out
(gmon.out：-pg產生的一些額外程式碼)
### time(不用gprofile)
=> gcc table.c -o table
=> time ./table
real：程式執行真正花的時間(打下指令~程式執行結束)
user：聽不太懂(好像是real*你有幾核心同時在跑)
sys：作業系統核心花的時間(system)

## 使用gdb反組譯
>就會出現組合語言的程式碼
可以看他實際到底是怎麼執行的

=> gdb ./table
=> disassemble main
(main可替換成其他想對其做反組譯的對象的樣子嗎)

## valgrind
>檢查記憶體的相關問題
>分析各個東東佔的時間、記憶體之類的
### 安裝
=> sudo apt install valgrind
=> sudo apt install kcachegrind
(kcachegrind：圖形化界面)
### 編譯
=> gcc -g table.c
=> valgrind --tool=callgrind ./a.out
=> kcachegrind callgrind.out.####
>檔名會叫callgrind.out.####
#：數字
可以先ls找到檔名再進行
他會幫你叫出一個超酷視窗
![](https://i.imgur.com/Mev8t83.png)

<mark>但其實結果(消耗的時間)並不精準</mark>
<mark>但對記憶體檢查很有幫助</mark>
>因為他會幫你重新編譯並在每個指令加上額外的檢查程式碼
## gedit
=> gedit table.c
=> gedit table.c &
可以看他的程式碼(幫你打開)
有加&代表執行在background
醬這邊就不會被鎖住，可以繼續打其他指令
## rm
=> rm table.c
刪除檔案

## perf
>![](https://i.imgur.com/acCLe5S.png)
使用perf可以觀看各個執行單元的使用情況
### 安裝
=> sudo apt install linux-tools-common
之後就打
=> perf
看他要你安裝甚麼裝一裝就行

### 介紹
http://wiki.csie.ncku.edu.tw/embedded/perf
perf的底層分為二種，分別是
* hardware performance counter：硬體事件
* software events：軟體事件

我們要用的是hardware performance counter
https://en.wikipedia.org/wiki/Hardware_performance_counter
>透過這些counter可以了解軟體在CPU內執行的具體情形

### sandy bridge
>好像不太重要的樣子

好像是把資料先存進buffer讓網路看起來流暢
但醬會導致有延遲時間

### perf指令
![](https://i.imgur.com/IC4yvs5.png)

=> sudo perf top
![](https://i.imgur.com/iTsDlt5.png)
偵測每個指令花了多少的CPU cycles(不知道就看圈起來那裡)
>這邊的cycle可替換為量測其他CPU的效能

p:精準(p越多越精準)

![](https://i.imgur.com/pFXiGw5.png)
=> sudo perf top -e branch-instructions
(branch-instructions可替換為圖下面其他的(量測其他CPU的效能))
=> perf list
老師介紹了裡面的東東我也是沒聽太懂

# ch02.3 使用clock_gettime
>非常精準的量測時間的函數
>總之就是介紹clock_gettime

## -Wall
=> gcc -Wall...
提示型別轉換
這類型的任何問題都會回報

## 圖形化介面
### Geany
>好像很受歡迎的樣子
### Visual Studio Code
=>-exec 指令
必須先打-exec後面再接linux指令才能跑
### Clion
>可試用1個月

相較於eclipse比較不吃記憶體
### Eclipse

# ch04.1 檔案輸入與輸出
## 檔案在linux是什麼樣子
![](https://i.imgur.com/0AeVkTX.png)
![](https://i.imgur.com/3sNJ9A8.png)
檔案指標會自動往後移動100bytes
空洞：可能檔案裏面這部分就是沒寫資料(邏輯上有佔空間但可能記憶體根本就沒有配空間給他)
![](https://i.imgur.com/hTPAkBr.png)
檔案系統支援file hole以避免浪費太多磁碟空間
## ex:mycp
要include 很多東西喔
This is [an example][id] reference-style link.
![](https://i.imgur.com/VInLhnn.png)
RDONLY:只讀
WRONLY:只寫
CREAT:若檔案不存在就創一個
後面兩個是權限的後面再說
## open
![](https://i.imgur.com/Tyt6yak.png)
<mark>open回傳當下可用的最小號碼</mark>
    stdout：os稍微優化
    stderr：馬上做(os沒有優化空間)
![](https://i.imgur.com/hmCxuIc.png)
mode:權限(owner, group, others)
![](https://i.imgur.com/1vEKSzI.png)
### 自學open
=> man 2 open
### open重要參數
![](https://i.imgur.com/jJuOhtV.png)
## read
![](https://i.imgur.com/jpWMKAM.png)
## write
![](https://i.imgur.com/qSLK2sc.png)
## perror
>印出比較詳細一點的錯誤訊息
![](https://i.imgur.com/KA6sNOm.png)
## errno
>error number
![](https://i.imgur.com/ov2leP8.png)
## close
>把檔案關掉
>把檔案內資料清空並讓釋放的資源ㄟ...free之類的
>忘記close的話會浪費系統很多資源

=> lsof - list open files
查看程式打開了哪些檔案與是否忘記關
## 自我學習
![](https://i.imgur.com/IqK7CCJ.png)
不知道在幹嘛

# ch04.2 lseek & file holes
## hole.c
![](https://i.imgur.com/TmIGjEB.png)
SEEK_SET：從頭
SEEK_CUR：從目前檔案指標位置
SEEK_END(應該是不確定)：從尾

## lseek()
>檔案指標
>不會動到i/o
>描述檔案目前在第幾個byte做讀寫
>不會真的移動或讀寫(虛擬的)
![](https://i.imgur.com/ALzffTo.png)
### lseek的whence
![](https://i.imgur.com/UnehhHG.png)

![](https://i.imgur.com/BXT34BA.png)


## 進階版mycp.c
![](https://i.imgur.com/OKwTeMU.png)
## 小節
![](https://i.imgur.com/q9D2BOt.png)

# ch04.3 sync & fsync & fdatasync
![](https://i.imgur.com/p3jjIdW.png)
meta-data：
例如：檔案的修改日期、檔案的大小、檔案的瀏覽日期等等，這些外加的資料都「附屬」於該檔案，因此稱之為meta-data
<mark>我也沒聽太懂，要用的時候建議再回去看一下</mark>

## 三個比較的實際執行
還沒看

# ch04.4 鎖定檔案flock
## 良心鎖v.s.強制鎖
**良心鎖**：每個process要存取檔案時要自己呼叫lock鎖定此檔案，而若有人已lock此檔，則lock不會成功，直到前一個人unlock後才能繼續執行。
若前一人執行lock，但你不執行而直接存取檔案，是可行的。
=>只防乖乖lock的人無法同時存取檔案
**強制鎖**：若不執行lock而直接存取則會失敗，其他同良心鎖
## flock-良心鎖(advisory locking)

## flock.c
![](https://i.imgur.com/Tn1vtEZ.png)
**LOCK_SH**：share lock/read lock，允許兩人同時讀取資料
**LOCK_EX**：exclusive lock/write lock，一次只能一人讀取資料
**LOCK_UN**：unlock，解除鎖定

## flock-強制鎖(mandatory locking)

### 預備動作
![](https://i.imgur.com/5M44wDe.png)
三行順序不能調換
=> sudo mount -oremount.mand /
不知道為什麼寫醬才能正確執行

<mark>上面都做完之後這個檔案就可以做強制鎖了！</mark>

## 小結
![](https://i.imgur.com/ru6977g.png)

# ch05 c標準輸出入函數庫與作業系統

## 開檔、寫檔、讀檔
![](https://i.imgur.com/ruqrSq5.png)
**./tmp**:路徑名
**w**:開啟模式
![](https://i.imgur.com/knQkcfT.png)
### fopen的mode參數
![](https://i.imgur.com/qA4Hgx3.png)
### stdin,stdout,stderr
![](https://i.imgur.com/HvNgCm3.png)
### 自學:fileno
>回傳fd，跟作業系統溝通時用到
### fprintf
![](https://i.imgur.com/3ITsBr3.png)

![](https://i.imgur.com/nfaI7LS.png)
### 檔案位置
![](https://i.imgur.com/nHcdjgN.png)
### 練習append+fseek
![](https://i.imgur.com/gcCmVBv.png)

## buffer
>增加程式效能
1. c函數庫的buffer
2. os的buffer
3. 硬體(hardward)的buffer
### c函數庫的buffer
>把東西合併一起傳遞
![](https://i.imgur.com/YCrMDAI.png)
### 設定buffer的大小
![](https://i.imgur.com/amgHuwV.png)
這些都可以用但先介紹setvbuf
#### setvbuf
![](https://i.imgur.com/G6aDF0n.png)
**unbuffered**:例:stderr寫進去馬上傳遞
**line buffered**:跟互動有關的，遇到換行符號才換
**fully buffered**:通常用在寫到檔案，滿了再傳比較有效率

範例程式：
![](https://i.imgur.com/bwu4VML.png)

## 讀寫檔案，及檔案結尾
![](https://i.imgur.com/jQSQXll.png)
### errors及EOF
![](https://i.imgur.com/PDHUbpH.png)
### 範例
![](https://i.imgur.com/11Z0ziB.png)
### 小結
1.使用stream雖然比較方便，速度也往往比較快，但要注意glibc如何管理buffer
2.較大的buffer速度比較快，但萬一系統斷電或當機，也要冒比較大的風險
## 製造系統中唯一的檔案
>一個系統的唯一暫存檔
>每隔一段時間自動幫他暫存
![](https://i.imgur.com/E6ptS4s.png)
### mktemp
![](https://i.imgur.com/WRMVuAn.png)
![](https://i.imgur.com/LsmbA26.png)
![](https://i.imgur.com/dY15T3l.png)
1.產生檔名
2.製造檔案
### 小結
![](https://i.imgur.com/xNy8lUj.png)

## 未介紹的部分
>對亞洲字元的支援
### wchar.h
### uchar.h

# ch06
## ch06.1 檔案及目錄

### ls -alh
![](https://i.imgur.com/PD6oNWZ.png)

.開頭的都是隱藏檔，其他是普通檔案
r=>讀 w=>寫 x=>可否執行 l=>link捷徑
三組各自代表不同人所擁有的權限：
最前面那欄:一槓(-):檔案，d:目錄，l:link捷徑
-__1__-__2__-__3__-
第一組：owner
第二組：group
第三組：others

123那個是hard-link個數
中間那個是檔案大小(沒列h的話顯示的會是byte大小)

![](https://i.imgur.com/d1ChUaN.png)
![](https://i.imgur.com/Be0fZVh.png)
![](https://i.imgur.com/UKOZjmD.png)
![](https://i.imgur.com/9LS3kwr.png)
![](https://i.imgur.com/KPMf9yA.png)

## ch06.2 檔案的特殊屬性set-uid
![](https://i.imgur.com/ajmsuPp.png)
>執行者:可讀自己的檔案
>檔案owner:執行時就不能看到自己的檔案了，只能看到該檔案owner的檔案

需要set-uid能在兩者之間切換
![](https://i.imgur.com/rJKG006.png)
>euid:執行者
>ruid:檔案owner

例外
![](https://i.imgur.com/rzR7CIk.png)

### 應用:password
![](https://i.imgur.com/adlXJQB.png)

### 超級ls
![](https://i.imgur.com/5lg7Dga.png)

...

### sticky bit
>現在已經沒有作用了，以前建在檔案上面，現在建在目錄上

![](https://i.imgur.com/WXBDvUZ.png)

## ch06.3 硬連結及軟連結

### hard link
![](https://i.imgur.com/etqnTlS.png)
>只可連向檔案不可連向目錄為了避免迴圈
>要連目錄就用soft link
>目前有兩個link指向這個檔案=>2
>hard link上只會有數字(檔案編號)

### soft link
![](https://i.imgur.com/Irt9UPO.png)
>soft link不會影響數量(2)，他只計hard link
>partition就是根目錄裡的東東(c槽d槽那種)

### 硬碟的處理
![](https://i.imgur.com/hP5RzUa.png)
>unix裡面掛載的目錄數量可以無限多
>windows有限

### 目錄系統、檔案系統
![](https://i.imgur.com/UofZ14a.png)
![](https://i.imgur.com/R6F9a5x.png)
>/etc/fstab:只有super user可改

#### unix中的file
![](https://i.imgur.com/T1kQV2s.png)

#### soft link狀況
![](https://i.imgur.com/ozItTYT.png)
>要有從頭到該檔案路徑下所有檔案的存取權
>hard link就不用
>若file 6消失，link依然會指向同一個位置，直到真正存取時，作業系統才會發現soft link指向的是不存在的東東(若新建一個file 6，仍能存取這個新的file 6)

### 小結
![](https://i.imgur.com/VKjsdnV.png)

## ch06.4操作目錄及檔案屬性

### mkdir
![](https://i.imgur.com/I0yxAco.png)
>umask:避免權限設定錯誤

### rmdir
![](https://i.imgur.com/OU57vPW.png)
>操作前還是要check權限的

### chdir
![](https://i.imgur.com/MltXAeL.png)

### getcwd
![](https://i.imgur.com/QPv8fJi.png)
>pwd回傳目前工作目錄的絕對路徑
>PATH_MAX:有可能不是常數！！

比起用malloc，可以用get_current_dir_name
![](https://i.imgur.com/tjiQZob.png)
>直接分配夠大的buffer，回傳buffer address，用完要記得free掉

## ch06.5 條列目錄裡所有的物件

### ls
![](https://i.imgur.com/IFoK76y.png)
> 目錄是搜尋樹，不是文字檔(但原本設定是文字檔)

### dirent
>列出目錄中東東
![](https://i.imgur.com/zMjEgGQ.png)
#### dir
![](https://i.imgur.com/41Mavwz.png)
#### listDir
![](https://i.imgur.com/ljQ2bHd.png)
![](https://i.imgur.com/jyJ3Oqz.png)

## ch06.6 利用stat讀取檔案屬性
>讀的屬性為inode的屬性(較完整)
>更進階版的dir

![](https://i.imgur.com/3PDYeMY.png)
![](https://i.imgur.com/RBT0QcM.png)
>st_blocks:佔據多少檔案大小

**atime:上次存取的時間
mtime:上次修改的時間
ctime:上次修改inode的時間(不能改，上面兩個其實都可以改)**
> linux未提供函數修改ctime


![](https://i.imgur.com/jZEkTS1.png)
>這邊的至少都一定要記得

### dir2
![](https://i.imgur.com/WTnxwJA.png)
![](https://i.imgur.com/ZJ1IdNF.png)
![](https://i.imgur.com/4ao2AmH.png)
![](https://i.imgur.com/ieb5tIC.png)

## ch06.7 檔案的操作
umask
>最大權限
![](https://i.imgur.com/VSbu8Lx.png)
![](https://i.imgur.com/vyJjf9X.png)
![](https://i.imgur.com/oaaFjMo.png)

以下都是umask的功能
### unlink
![](https://i.imgur.com/ovTuKJw.png)

### rename
![](https://i.imgur.com/a2IfRno.png)

## ch06.8 設定檔案的ACL
![](https://i.imgur.com/o5mTot8.png)
![](https://i.imgur.com/JTAVpEV.png)
> 這兩個是指令
> 理論上可以設置無限個使用者的讀取權限
> 實際上要看檔案配給ACL的空間大小

=>getfacl
![](https://i.imgur.com/EzDeBw9.png)

=>setfacl
![](https://i.imgur.com/QoDTuk7.png)
![](https://i.imgur.com/45uytCJ.png)
>user: :rw- 沒有特別寫那就是owner(預設的那個)
>group的就是group

mask:若有umask => mask會覆蓋掉umask的設定

![](https://i.imgur.com/aGqXiPt.png)

### 小結
![](https://i.imgur.com/h0OH0Ls.png)

## ch06.10 監聽檔案異動
> 也可以監聽目錄(特別的檔案)

### inotify
![](https://i.imgur.com/1oL34ss.png)

### 小結
![](https://i.imgur.com/l0wTZG5.png)

