Try   HackMD

2016q3 Homework2 (phonebook-concurrent)

contributed by <heathcliffYang>

github

目標

  • 學習第二週提及的 concurrency 程式設計
  • 學習 POSIX Thread
  • 學習效能分析工具
  • code refactoring 練習
  • 探索 clz 的應用

Code 理解

原code 其實從entry找不到detail

避免貼出完整的程式碼,你應該只要列出「關鍵」的部分。 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 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 ->

    /* 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) 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. dprintf https://linux.die.net/man/3/dprintf

完全不是這回事,dprintf 定義在 debug.h 中,過度仰賴 Google 搜尋的結果,下場就是捨近求遠,浪費自己的時間。下次請先研究程式碼 jserv

  1. off_t

C 標準函式庫和 POSIX 規範建議 typedef 定義過的型態標註 "_t" 名稱 jserv

  1. pthread_setconcurrency()
  2. 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 :
  3. mmap()
  4. int pthread_getconcurrency(void);

檔案處理參考資料