---
# System prepended metadata

title: Thread
tags: [OS]

---

<style>
H2{color:#BF0060 !important;}
H3{color:#009393 !important;}
p{color:Black !important;}
li strong {color:#4682b4 !important;}
</style>

# Thread
## **TCP Echo Server** 
### **Multiple Processes (Ver. 2)**
* **child process**
    * `要close(listenfd)`
    * `doit 做完 close(connfd), main 要再 close(connfd)`
* <img src="https://i.imgur.com/Fa7w0GK.png" width = "400"/>

### **Multiple Thread (Ver. 3)**
* `call pthread_create instead of fork`
* **child thread**
    * `不用close(listenfd), since creating new thread doesn't affect the ref_cnt for open descriptor`
    * `doit 做完 close(connfd), main不用再close(connfd)`
* <img src="https://i.imgur.com/ZdMaqNu.png" width = "400"/><img src="https://i.imgur.com/ShtoAGi.png" width = "400"/>

## **sharing data among threads** 
### **static vs. stack-dynamic**
* `process是copy, thread 共享 static`
* <img src="https://i.imgur.com/28uM2b9.png" width = "500"/>
### **data inconsistence**
* `原因：hardware instr is not atomic : `
    `mov eax, a `
    `add 1`
    `mov a, eax`
    * <img src="https://i.imgur.com/pv3RTIm.png" width = "500"/>
### **calling non-rentrant function**
* `避免re-entrant`
    * `avoid static data`
    * `synchronization primitives`
    * `程式撰寫`
        * avoid static data
        * 每個 funct 有自己的 structure：
    caller packs all the args and stores static var into a structure
    * `provide thread specific data`

### **provide thread-specific data**

* **Key Structure**
    * `For each process, kernal maintain a KEY structure (an array)`
        * <img src="https://i.imgur.com/qIrgleE.png" width = "400" /></img>
* **Concept**
    * `利用 mapping 取得 data`
        * <img src="https://i.imgur.com/HsmbMCg.png" width = "400"/></img>
* **Steps**
    * call ==pthread_key_create / pthread_once== 向 kernal 要一個未使用的 key idx 作為 static data 的 name
    * thread call ==malloc== 取得 heap-dynamic storage，用以儲存static data
    * thread call ==pthread_setspecific(key, ptr)== 將此 storage 位址對應到取得的Key index
    * 在 re-ent funct call ==pthread_getspecific(key)== 取得 key idx 對應的 thread-specific data
    <br>
    * <img src="https://i.imgur.com/f6pYizC.png" width = "400"/></img>
* **Storage**
    * `Different Threads Have Different Storages for the Same Name / Idx`
    `One Name to Different Location`
        * <img src="https://i.imgur.com/W37hS6b.png" width = "400"/></img>


* **KEY idx 存取**
    * 為確保 thread-safe 之變數 ：利用 pthread_key_create 得到一個唯一的key index
    * 不同 key idx 供同一 function 中不同 static data 使用
    *  對同一 static data，由第一個執行此 function 的 thread 去請求key idx 即可。因為每次呼叫會傳回新的未使用的 idx。
    * pthread_once 來達成此功能 (對同一 static data 只請求一次 key idx)

###### tags: `OS`