# 2016q3 Homework2 (phonebook-concurrent) contributed by <`heathcliffYang`> [github](https://github.com/heathcliffYang/phonebook-concurrent) ## 目標 * 學習第二週提及的 concurrency 程式設計 * 學習 POSIX Thread * 學習效能分析工具 * code refactoring 練習 * 探索 clz 的應用 # Code 理解 原code 其實從entry找不到detail >> 避免貼出完整的程式碼,你應該只要列出「關鍵」的部分。 [name=jserv] >> 好的!! 打完之後會改!!謝謝老師 ### .h 1. entry : 依lastName的搜尋單元,有一個指到detail的pinter跟entry搜尋結構中的下一個pointer 2. detail : 各lastName的詳細資料 ### .c 主要是將entry搜尋結構跟detail的結構分開 1. findName : 順著找,找到後malloc lastName 字串要放的地方,把在結構中已搜尋到的字串清除 2. append : Pthread工作: 把malloc好的append_a加入到append_a結構中 ### main.c 1. 在一開始就分配一大區memory給檔案裡的entry,因為malloc是system call,減少叫用次數也可以減少時間。 ---> ==覺得可以學習之處== 2. mmap的技術 >> 應該一併指出原本不足之處,然後你怎麼做 code refactoring [name=jserv] ## Concurrency 策略 參考原程式碼概念,建立兩種結構:entry搜尋結構 與 detail 對應詳細資料的結構 ### .h entry : lastName, pNext(指向下個entry), pdetail(指向對應的detail) detail: 其餘data, pdNext(指向下個detail), pEntry(指向對應的entry) ### .c - [ ] append() #### 1. malloc an entry pool & detail pool 要先知道檔案大小->lineNum紀錄行數->最後因為呼叫檔案的考量,所以把此動作提到main()去了,並且做分流,所以orig並不會改到需要做此動作 #### 2. create pthread 1. 在思考到底要從append分出thread,還是在main裡面分thread工作--->==最後先做從main分thread== 2. 之後計畫在把main.c改好分流opt&orig的執行部分 3. 嘗試在data set加入其他資訊,實際面對要讀入除了lastName以外的資料時,多個thread要怎麼同時從檔案中讀入資料?之後再將資料傳入detail裡--->==not yet== > 跟hugikun999討論到,其他detail的資料應該是放在另外一個檔案,還是跟lastName同一個檔案?若是放在同一個檔案,那就會面臨到一個問題:可以同時fgets()嗎?若不能的話,就要在一輪迴圈內一起做entry跟detail的資料配置 ---> 詳見main.c之1 #### 3. 把detail跟entry串起 - [ ] append_detail() 將detail資料補上 - [ ] findName() ### main.c ==**遇到的問題** :== 在malloc detail pool時,detail_pool得到的值printf出來是nil -> 隨後接下來的就core dump -> ```c /* Get the file size and malloc an entry pool and a detail pool*/ char line1[MAX_LAST_NAME_SIZE]; int lineNum; while (fgets(line1, sizeof(line1), fp)) { lineNum++; } entry *entry_pool = (entry *) malloc(sizeof(entry)*lineNum); printf("entry_pool is at %p\n", entry_pool); /* build the entry */ entry *pHead, *e; pHead = entry_pool; printf("size of entry : %lu bytes\n", sizeof(entry)); e = pHead; e->pNext = NULL; /* build the detail */ // detail *detail_pool = (detail *) malloc(sizeof(detail) * lineNum); // pHead->pdetail = detail_pool; detail *d = (detail *) malloc(sizeof(detail)); pHead->pdetail = d; printf("e->pdetail : %p\n", e->pdetail); ``` 原因是malloc本身的大小限制 >> 所以寫程式之前,一定要讀手冊: [malloc(3)](https://linux.die.net/man/3/malloc) [name=jserv] >> 好的!! 謝謝老師QQ 以後會先看使用手冊 #### 1. 關於malloc detail的討論 - 克服不可同時讀取 mmap() -> malloc detail 四個部分 -> 分給4個thread建 -> **not yet 部分 :** thread 回傳最末pointer (用pthread_join()處理)-> 串起 ==主要目標:把pthread parameter的傳遞看懂 & open file相關== 因為對記憶體位址表示的觀念不足,在memory pool的shift處理花了很多時間 - Sequencial ==fopen()與open()的差別(思考中)== ## C programming 1. `int strncasecmp(const char *s1, const char *s2, size_t n);` 比較前n個字串長度 2. `memset(address, '\0', n)`將某一記憶體區段的前 n 個字元全部設定為某一字元 3. <s>`dprintf` https://linux.die.net/man/3/dprintf </s> >> 完全不是這回事,`dprintf` 定義在 `debug.h` 中,過度仰賴 Google 搜尋的結果,下場就是捨近求遠,浪費自己的時間。下次請先研究程式碼 [name=jserv] 4. off_t >> C 標準函式庫和 POSIX 規範建議 typedef 定義過的型態標註 "_t" 名稱 [name=jserv] 5. `pthread_setconcurrency()` 6. `int open(const char *pathname, int flags, mode_t mode);` **file creation flags** : O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE, and O_TRUNC. **file status flags** : can be retrieved and (in some cases) modified **mode** : 7. [`mmap()`](http://man7.org/linux/man-pages/man2/mmap.2.html) 8. [`int pthread_getconcurrency(void);`](http://man7.org/linux/man-pages/man3/pthread_getconcurrency.3.html) [檔案處理參考資料](http://pydoing.blogspot.tw/2010/07/c-stdfile.html)