2016q3 Homework2 (phonebook-concurrent)
===
contributed by <`SarahYuHanCheng`>
##### tag: `sarah`,`phonebook-concurrent`
- [ ] concurrency 教材的認知
- [ ] 程式正確性驗證
- [ ] 效能分析實驗 (必須要有圖表)
- [ ] 以及充份說明你如何改善效能
### Reference
* [TempoJiJi](https://github.com/TempoJiJi/phonebook-concurrent/commit/a659b6d0babf1a8ac56b9108dd39031700980d02)
* [raypan](https://hackmd.io/CYIw7ADAphwKwFoBmcAcqEBYoCYBsCIewAnAiSBcJmFAMz4DGQA=#)
* [jkrvivian](https://hackmd.io/CYIw7ADAphwKwFoBmcAcqEBYoCYBsCIewAnAiSBcJmFAMz4DGQA=#)
*
## Concurrency
舉了很好懂且生活化的例子,以下摘錄片段:
譬如說,一邊走路一邊講電話就同時做兩件事(走路和講電話),一邊寫報告一邊上網聊天也是如此。然而這兩個同時做兩件事的例子卻有著很微妙的差異,前者我們真的是在每一瞬間都是同時進行兩件事(走路和講電話);後者卻不然,大多人都是寫一段報告、就跳過去聊天、再寫報告、再聊天、等等,幾乎不可能在每一瞬間都同時在寫報告和聊天。
兩個例子中前者(兩件事齊頭並進)的處理方式叫做平行(parallel),後者在兩件事中交錯執行、但每一瞬間每件事都有點進展;並行(concurrent,此地採用國內的譯名)指的是交錯執行和平行兩者,所以並行比平行在意義上較廣。

More parallelization :

## mmap
在linux下使用mmap實在是相當方便,看到linux manual,除了解決memory management 的問題外,還因為是VMA,所以使用fd讀寫時已經確保過image segamentation正確,這如果是在FreeRTOS上就會是相當大的工程。
`void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);`
`int munmap(void *addr, size_t length);`
所以在append時,下方第12行不需要再做malloc的動作,因為已經使用過mmap獲取空間與紀錄尾端位址。
```clike=
append_a *new_append_a(char *ptr, char *eptr, int tid, int ntd,
entry *start)
{
append_a *app = (append_a *) malloc(sizeof(append_a));
app->ptr = ptr;
app->eptr = eptr;
app->tid = tid;
app->nthread = ntd;
app->entryStart = start;
app->pHead = (app->pLast = app->entryStart);
return app;
}
```
說到append就想到在找mmap末端時,`main`中使用`fsize()`取得檔案大小:
`off_t fs = fsize(ALIGN_FILE);`
這個fs取名取的過於簡略,影響閱讀,先換成fileOffset。
同樣的問題發生在append_a上,將其修改
```clike=
typedef struct _append_a {
char *ptr;
char *ptrEnd;
int threadId;
int threadNum;
entry *entryStart;
entry *pHead;
entry *pLast;
} append_a;
```
## Asynchronous
## Execution
**threadNUM= 4**
所以才使用do{}while(0)改寫成:
```clike=
#define FOO(x) do { foo(x); bar(x); } while (0)
if (condition)
FOO(x);
else
....
```
`pthread_setconcurrency(THREAD_NUM + 1);`
然後來討論thread的使用:
這邊的`join`會使得所有的thread在等待最慢的一個thread,附上manu
The pthread_join() function waits for the thread specified by thread to terminate. If that thread has already terminated, then pthread_join() returns immediately. The thread specified by thread must be joinable.
```clike=
clock_gettime(CLOCK_REALTIME, &mid);
for (int i = 0; i < THREAD_NUM; i++)
pthread_create( &tid[i], NULL, (void *) &append, (void *) app[i]);
for (int i = 0; i < THREAD_NUM; i++)
pthread_join(tid[i], NULL);
```
所以改成thread pool:使用threadpool-mbrossard
結果:
## Reference
* [Locks, Mutexes, and Semaphores: Types of Synchronization Objects](https://www.justsoftwaresolutions.co.uk/threading/locks-mutexes-semaphores.html)
* [An Introduction to Lock-Free Programming](http://preshing.com/20120612/an-introduction-to-lock-free-programming/)
* [MMAP(2) Linux Programmer's Manual ](http://man7.org/linux/man-pages/man2/mmap.2.html)
* [do { … } while (0) — what is it good for? [duplicate]](http://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for)