/* 这是一个使用例子。 */ /* 在我的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;
} |