编写一个Pthreads程序实现梯形积分,使用一个共享变量来表示所有线程计算结果的总和,选择使用忙等待、互斥量和信号量来保证临界区的互斥,并分析方法的优点和缺点。
OpenMP实现求矩阵均值最大值以及最小值
OpenMP实现数据统计
Pthreads实现任务队列
Pthreads实现梯形积分
visual studio 2019配置Pthreads和OpenMP
CodeBlocks 17.12配置Pthreads和OpenMP
#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;
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;
thread_count = 4;
thread_handles = (pthread_t*)malloc(thread_count*sizeof(pthread_t));
printf("请输入要划分成的份数:");
scanf("%d", &n);
h = 2*1.0/n;
while(1){
printf("---------请选择功能---------\n");
printf("1.忙等待\t2.互斥量\t3.信号量\t0.退出\n");
scanf("%d", &order);
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("结果:%lf\t用时:%lf\n", sum_waiting,(double)(end_time-start_time)/CLK_TCK);//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("结果:%lf\t用时:%lf\n", sum_mutex,(double)(end_time-start_time)/CLK_TCK);//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("结果:%lf\t用时:%lf\n", sum_semaphores,(double)(end_time-start_time)/CLK_TCK);//CLOCKS_PER_SEC);
break;
case 0:
printf("退出成功!\n");
return 0;
default:
printf("输入有误,请重新输入!\n");
break;
}
}
return 0;
}
void* Thread_sum_waiting(void* rank){
long my_rank = (long)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);
b = ((i+1)*h)*((i+1)*h);
while(flag!=my_rank);
sum_waiting += (a+b)*h/2;
flag = (flag+1)%thread_count;
}
}
void* Thread_sum_mutex(void* rank){
long my_rank = (long)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);
b = ((i+1)*h)*((i+1)*h);
pthread_mutex_lock(&mutex);
sum_mutex += (a+b)*h/2;
pthread_mutex_unlock(&mutex);
}
}
void* Thread_sum_semaphores(void* rank){
long my_rank = (long)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);
b = ((i+1)*h)*((i+1)*h);
sem_wait(&semaphore);
sum_semaphores += (a+b)*h/2;
sem_post(&semaphore);
}
}