用Pthreads计算积分的一个小例子
说明:编写一个Pthreads程序使用梯形积分求出函数𝑓(𝑥)=𝑥
2+𝑥 在区间[𝑎,𝑏]的定积分。使
用一个共享变量来表示所有计算线程的总和。在程序中使用忙等待,互斥量和信号量三种来保
证临界区的互斥。命令行如下编译:
$./pth_trap <number of threads> <number of method>
😉一、代码展示
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <time.h> int thread_count, flag = 0; long n, order, start_time, end_time, a, b; double h, sum_waiting, sum_mutex, sum_semaphores; pthread_mutex_t mutex; sem_t semaphore; void *Thread_sum_waiting(void *rank); void *Thread_sum_mutex(void *rank); void *Thread_sum_semaphores(void *rank); int main() { long i; pthread_t *thread_handles; scanf("%d %d", &thread_count, &order); if (order == 1) { printf("Using method busy-wait\n"); } else if (order == 2) { printf("Using method mutex\n"); } else { printf("Using method signal\n"); } thread_handles = (pthread_t *) malloc(thread_count * sizeof(pthread_t)); printf("Input the value of a,b,n:\n"); scanf("%d %d %d", &a, &b, &n); h = (b - a) * 1.0 / n;//求出来区间分为n份之后每一份的长度 switch (order) { case 1: sum_waiting = 0; start_time = clock(); for (i = 0; i < thread_count; i++) pthread_create(&thread_handles[i], NULL, Thread_sum_waiting, (void *) i); for (i = 0; i < thread_count; i++) pthread_join(thread_handles[i], NULL); end_time = clock(); printf("Estimate of the integral:%lf\n", sum_waiting);//CLOCKS_PER_SEC); break; case 2: sum_mutex = 0; start_time = clock(); pthread_mutex_init(&mutex, NULL); for (i = 0; i < thread_count; i++) pthread_create(&thread_handles[i], NULL, Thread_sum_mutex, (void *) i); for (i = 0; i < thread_count; i++) pthread_join(thread_handles[i], NULL); pthread_mutex_destroy(&mutex); end_time = clock(); printf("Estimate of the integral:%lf\n", sum_mutex);//CLOCKS_PER_SEC); break; case 3: sum_semaphores = 0; start_time = clock(); sem_init(&semaphore, 0, 1); for (i = 0; i < thread_count; i++) pthread_create(&thread_handles[i], NULL, Thread_sum_semaphores, (void *) i); for (i = 0; i < thread_count; i++) pthread_join(thread_handles[i], NULL); sem_destroy(&semaphore); end_time = clock(); printf("Estimate of the integral:%lf\n", sum_semaphores);//CLOCKS_PER_SEC); break; } } void *Thread_sum_waiting(void *rank) { long my_rank = (uintptr_t) rank; long long i; double a, b; long long my_n = n / thread_count; long long my_first_i = my_n * my_rank; long long my_last_i = my_first_i + my_n; for (i = my_first_i; i < my_last_i; i++) { a = (i * h) * (i * h) + (i * h);//x2+x b = ((i + 1) * h) * ((i + 1) * h) + ((i + 1) * h);//x2+x while (flag != my_rank); sum_waiting += (a + b) * h / 2; flag = (flag + 1) % thread_count; } } void *Thread_sum_mutex(void *rank) { long my_rank = (uintptr_t) rank; long long i; double a, b; long long my_n = n / thread_count; long long my_first_i = my_n * my_rank; long long my_last_i = my_first_i + my_n; for (i = my_first_i; i < my_last_i; i++) { a = (i * h) * (i * h) + (i * h);//x2+x b = ((i + 1) * h) * ((i + 1) * h) + ((i + 1) * h);//x2+x pthread_mutex_lock(&mutex); sum_mutex += (a + b) * h / 2; pthread_mutex_unlock(&mutex); } } void *Thread_sum_semaphores(void *rank) { long my_rank = (uintptr_t) rank; long long i; double a, b; long long my_n = n / thread_count; long long my_first_i = my_n * my_rank; long long my_last_i = my_first_i + my_n; for (i = my_first_i; i < my_last_i; i++) { a = (i * h) * (i * h) + (i * h);//x2+x b = ((i + 1) * h) * ((i + 1) * h) + ((i + 1) * h);//x2+x sem_wait(&semaphore); sum_semaphores += (a + b) * h / 2; sem_post(&semaphore); } }
🐱🐉二、运行结果