contributed by <HaoTse
>
Getting Started With POSIX Threads
pthread_t a_thread;
pthread_attr_t a_thread_attribute;
void thread_function(void *argument);
char *some_argument;
pthread_create( &a_thread, a_thread_attribute, (void *)&thread_function,
(void *) &some_argument);
exit
的陷阱exit
都將導致 process 結束,而所有的 thread 也跟著一起結束了。所以如果要結束一個 thread ,我們必須使用 pthread_exit
這個函數。sleep
的陷阱sleep
時,講導致整個 process 停下來。這表示所有屬於這個 process 的 thread 也將跟著停頓下來。另外一個適用的函數是 pthread_delay_np
(np 表示 not portable)。
_np
表示 not portable,網路上找資料容易找到錯誤的材料,所以要回歸第一手資料。權威性的資料可參見 Open Group: Threads jserv
例如要讓程式停2秒可以使用下列方法
struct timespec delay;
delay.tv_sec = 2;
delay.tv_nsec = 0;
pthread_delay_np(&delay);
pthread_mutex_init(&mutex, pthread_mutexattr_default)
初始 mutexpthread_mutex_destroy(&mutex)
釋放 mutexmain.c
中 opt 版本需引入的標頭檔集中在 main.c
的前面方便閱讀
//include the needed header file and define marco when OPT
#if defined(OPT)
#include "file.c"
#include "debug.h"
#include <fcntl.h>
#define ALIGN_FILE "align.txt"
#ifndef THREAD_NUM
#define THREAD_NUM 4
#endif
#endif
phonebook_opt.c(append)
中的 for loop 為 while loop,因為 for loop 中條件敘述過長,不易閱讀
char *i = app->ptr;
while(i < app->eptr) {
app->pLast->pNext = j;
app->pLast = app->pLast->pNext;
app->pLast->lastName = i;
dprintf("thread %d append string = %s\n",
app->tid, app->pLast->lastName);
app->pLast->pNext = NULL;
i += MAX_LAST_NAME_SIZE * app->nthread;
j += app->nthread;
count++;
}
warning: ‘CPU_time’ defined but not used [-Wunused-function]
phonebook_opt.c
和 phonebook_opt.h
中的 static double diff_in_second(struct timespec t1, struct timespec t2)
前後加入 #ifdef PROFILE
確認是否開啟 PROFILE 模式。$ make DEBUG=1 PROFILE=1
main.c
中的第105行起的 for loop 為下列的樣子
pHead = app[0]->pHead;
dprintf("Connect %d head string %s %p\n", 0, app[0]->pHead->pNext->lastName, app[0]->ptr);
etmp = app[0]->pLast;
for (int i = 1; i < THREAD_NUM; i++) {
etmp->pNext = app[i]->pHead;
dprintf("Connect %d head string %s %p\n", i, app[i]->pHead->pNext->lastName, app[i]->ptr);
etmp = app[i]->pLast;
dprintf("Connect %d tail string %s %p\n", i, app[i]->pLast->lastName, app[i]->ptr);
dprintf("round %d\n", i);
}
做了兩個主要的修改
1.將 i = 0 的情況移出 for loop 減少 branch 的數量
2.更正原本程式的錯誤,原本為連接 pHead->pNext
,但應連接 pHead
才對
使用前面提到的 threadpool-mbrossard 實作
將 main.c
中的 thraed 改變為以下的操作方式
threadpool_t *pool = threadpool_create(THREAD_NUM, POOL_SIZE, 0);
for(int i = 0; i < THREAD_NUM; i++) {
app[i] = new_append_arg(map + MAX_LAST_NAME_SIZE * i, map + fs, i, THREAD_NUM, entry_pool + i);
threadpool_add(pool, &append, (void *)app[i], 0);
}
threadpool_destroy(pool, 0);
不過這裡執行時產生了 Segmentation fault,研究了一陣子沒有結論,在TempoJiJi 的筆記 中找到了答案,將 threadpool_destroy(pool, 0)
改成 threadpool_destroy(pool, 1);
就成功了。
HaoTse
sysprog21
phonebook
concurrent
POSIX Threads