/* 这是一个使用例子。 */
/* 在我的P4双核机器上,可以比单线程版本快20%,但复杂性远高于20%! :( */
#include "threadpool.h"
unsigned long long sum(unsigned long long start, unsigned long long end) { unsigned long long sum;
sum = 0; for (; start<=end; ++start) sum += start;
return sum; }
struct per_sum { unsigned long long sum, start, end; pthread_mutex_t lock; pthread_cond_t cond; };
void threaded_sum(void *voidp) { struct per_sum *per_sum = voidp;
printf("thread %p start\n", voidp);
if (!per_sum) { // printf("per_sum == NULL\n"); return; } per_sum->sum = sum(per_sum->start, per_sum->end); per_sum->start = per_sum->end = 0; pthread_mutex_lock(&per_sum->lock); printf("thread %p exit, end=%lld\n", voidp, per_sum->end); pthread_cond_signal(&per_sum->cond); pthread_mutex_unlock(&per_sum->lock); }
int main(void) { #define NR_THREADS 2 struct thread_worker* workers[NR_THREADS]; struct per_sum per_sums[NR_THREADS]; struct thread_pool *pool; int i;
unsigned long long start, end; unsigned long long result = 0; unsigned long long delta = 0x10ffffff;
// printf("mutli threading ... ");
pool = thread_pool_create(NR_THREADS, NULL); if (!pool) exit(-1);
for (i=0; i<NR_THREADS; ++i) { if (pthread_mutex_init(&per_sums[i].lock, NULL)) { printf("failed init mutex\n"); exit(3); } if (pthread_cond_init(&per_sums[i].cond, NULL)) { printf("failed init cond\n"); exit(4); } if (thread_pool_lend(pool, threaded_sum, (void*)&per_sums[i], &workers[i])) { printf("failed to lend thread %d\n", i); exit(5); } }
start = 0;
/* activate threads */ for (i=0; i<NR_THREADS; i++) { per_sums[i].start = start; per_sums[i].end = per_sums[i].start + delta; start = per_sums[i].end + 1; thread_pool_activate(workers[i]); }
for (i=0; i<NR_THREADS; i++) { pthread_mutex_lock(&per_sums[i].lock); while (per_sums[i].end != 0) pthread_cond_wait(&per_sums[i].cond, &per_sums[i].lock); result += per_sums[i].sum; pthread_mutex_unlock(&per_sums[i].lock); }
/* activate threads again */ for (i=0; i<NR_THREADS; i++) { per_sums[i].start = start; per_sums[i].end = per_sums[i].start + delta; start = per_sums[i].end + 1; thread_pool_activate(workers[i]); } end = per_sums[NR_THREADS-1].end;
for (i=0; i<NR_THREADS; i++) { pthread_mutex_lock(&per_sums[i].lock); while (per_sums[i].end != 0) pthread_cond_wait(&per_sums[i].cond, &per_sums[i].lock); result += per_sums[i].sum; pthread_mutex_unlock(&per_sums[i].lock); }
for (i=0; i<NR_THREADS; ++i) { if (thread_pool_giveback(pool, workers[i])) { printf("failed to giveback thread %d\n", i); exit(6); } pthread_mutex_destroy(&per_sums[i].lock); pthread_cond_destroy(&per_sums[i].cond); }
thread_pool_clean(pool); printf("sum = %lld\n\n", result); return 0; }
|