contributed by <nekoneko
>
參考資料: Chapter 2 - Designing Threaded Programs
thread pool
。thread pool
: 事先建立多個執行緒,我們稱之為thread pool,等到manager分配工作下來後,在從thread pool裡取出一個執行緒來做其工作。安裝
$ sudo apt-get install astyle cppcheck
$ script/install-git-hooks
intall-git-hooks是一個bash檔
#!/bin/sh
if ! test -d .git; then
echo "Execute scripts/install-git-hooks in the top-level directory."
exit 1
fi
ln -sf ../../scripts/pre-commit.hook .git/hooks/pre-commit || exit 1
echo
echo "Git commit hooks are installed successfully."
test -d .git
: 檢查.git
是否為存在且為資料夾$ sudo apt-get install mutrace
$ (for i in {1..8}; do echo $RANDOM; done) | mutrace ./sort 4 8
mutrace: Showing statistics for process sort (pid 13148).
mutrace: 3 mutexes used.
Mutex #0 (0x0x19649b0) first referenced by:
/usr/lib/mutrace/libmutrace.so(pthread_mutex_init+0xf2) [0x7f71d0c9f4b2]
./sort(tqueue_init+0x38) [0x401277]
./sort(tpool_init+0x6a) [0x4014cc]
./sort(main+0x161) [0x401c74]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f71d06d6830]
Mutex #2 (0x0x7f71ce2a5860) first referenced by:
/usr/lib/mutrace/libmutrace.so(pthread_mutex_lock+0x49) [0x7f71d0c9f6b9]
/lib/x86_64-linux-gnu/libgcc_s.so.1(_Unwind_Find_FDE+0x2c) [0x7f71ce0a1fec]
[(nil)]
Mutex #1 (0x0x603120) first referenced by:
/usr/lib/mutrace/libmutrace.so(pthread_mutex_init+0xf2) [0x7f71d0c9f4b2]
./sort(main+0x11d) [0x401c30]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f71d06d6830]
mutrace: Showing 3 most contended mutexes:
Mutex # Locked Changed Cont. tot.Time[ms] avg.Time[ms] max.Time[ms] Flags
0 153 38 25 0.040 0.000 0.002 Mx.--.
2 20 14 5 0.006 0.000 0.002 M-.--.
1 13 7 1 0.003 0.000 0.000 M-.--.
||||||
/|||||
Object: M = Mutex, W = RWLock /||||
State: x = dead, ! = inconsistent /|||
Use: R = used in realtime thread /||
Mutex Type: r = RECURSIVE, e = ERRRORCHECK, a = ADAPTIVE /|
Mutex Protocol: i = INHERIT, p = PROTECT /
RWLock Kind: r = PREFER_READER, w = PREFER_WRITER, W = PREFER_WRITER_NONREC
mutrace: Note that the flags column R is only valid in --track-rt mode!
mutrace: Total runtime is 1.189 ms.
$ addr2line -e sort 0x401277 0x4014cc 0x401c74
/home/jacklin/Documents/sys2016/week3/mergesort-concurrent/threadpool.c:15
/home/jacklin/Documents/sys2016/week3/mergesort-concurrent/threadpool.c:80
/home/jacklin/Documents/sys2016/week3/mergesort-concurrent/main.c:175
這邊共筆的範例是用括弧裡的位址(ex: 0x38),但在我電腦上要用中括弧裡的位址才能印出code的位置。cheng hung lin
tpool_init(pool, thread_count, task_run);
/* launch the first task */
task_t *_task = (task_t *) malloc(sizeof(task_t));
_task->func = cut_func;
_task->arg = the_list;
tqueue_push(pool->queue, _task);
tpool_init
中
tqueue_init(the_pool->queue);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
tqueue_init
中
the_queue->head = NULL;
the_queue->tail = NULL;
pthread_mutex_init(&(the_queue->mutex), NULL);
pthread_cond_init(&(the_queue->cond), NULL);
the_queue->size = 0;
return 0;
這邊對印address的code似乎沒看到mutex發生的情況,覺的自己在某方面上有不了解的
Locked
:Changed
:Cont.
:tot.Time[ms]
:avg.Time[ms]
:max.Time[ms]
:mutrace -h
data_contex
task_run
max_cut = thread_count * (thread_count <= data_count) + data_count * (thread_count > data_count) - 1;
main.c: task_run(void *)
static void *task_run(void *data)
{
(void) data;
while (1) {
task_t *_task = tqueue_pop(pool->queue);
if (_task) {
if (!_task->func) {
tqueue_push(pool->queue, _task);
break;
} else {
_task->func(_task->arg);
free(_task);
}
}
}
pthread_exit(NULL);
}
main.c: cut_func
threadpool.c: tpool_init
void *(*func)(void *)
初始。也就是說,每條thread做的就是func。threadpool.c: tqueue_*
tqueue_init:
tqueue_push:
int tqueue_push(tqueue_t *the_queue, task_t *task)
{
pthread_mutex_lock(&(the_queue->mutex));
task->last = NULL;
task->next = the_queue->head;
if (the_queue->head)
the_queue->head->last = task;
the_queue->head = task;
if (the_queue->size++ == 0)
the_queue->tail = task;
pthread_mutex_unlock(&(the_queue->mutex));
return 0;
}
void g_queue_free_full (GQueue *queue, GDestroyNotify free_func);
list.c, list.h:
#include <stdint.h>
...
typedef intptr_t val_t;
...
typedef struct node {
val_t data;
struct node *next;
} node_t;
typedef void *val_t;
typedef void (*print_funptr_t)(val_t,FILE *);
void list_print(llist *list, print_funptr_t funptr, FILE *fp);
merge, merge_sort, merge_list還沒看完,等了解完,再確認上面想法有沒有錯。cheng hung lin
nekoneko