job7/pi1.c: 使用2个线程根据莱布尼兹级数计算PI
- 莱布尼兹级数公式: 1 - 1/3 + 1/5 - 1/7 + 1/9 - ... = PI/4
- 主线程创建1个辅助线程
- 主线程计算级数的前半部分
- 辅助线程计算级数的后半部分
- 主线程等待辅助线程运行結束后,将前半部分和后半部分相加
前置学习内容
创建线程
等待线程
需要等待线程结束再结束进程,否则会有一半结果未输出。
思路
创建线程worker,主线程是master,worker负责前半,master负责后半,二者并发运行,互不干扰。
代码
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#define HALF 200
double PI;
double worker_output;
double master_output;
void *worker(void *arg){
double j;
worker_output=0;
for(int i=1;i<=HALF;i++){
j=i;
if(i%2==0)
worker_output-=1/(2*j-1);
else
worker_output+=1/(2*j-1);
}
return NULL;
}
void master(){
double j;
master_output=0;
for(int i=HALF+1;i<=2*HALF;i++){
j=i;
if(i%2==0)
master_output-=1/(2*j-1);
else
master_output+=1/(2*j-1);
}
}
int main(){
pthread_t worker_tid;
pthread_create(&worker_tid,NULL,worker,NULL);
master();
pthread_join(worker_tid,NULL);
PI=(worker_output+master_output)*4;
printf("PI= %f\n",PI);
return 0;
}
job7/pi2.c: 使用N个线程根据莱布尼兹级数计算PI
- 与上一题类似,但本题更加通用化,能适应N个核心
- 主线程创建N个辅助线程
- 每个辅助线程计算一部分任务,并将结果返回
- 主线程等待N个辅助线程运行结束,将所有辅助线程的结果累加
- 本题要求 1: 使用线程参数,消除程序中的代码重复
- 本题要求 2: 不能使用全局变量存储线程返回值
前置知识点
线程参数
参数类型
可以向线程入口函数传递任意类型的参数
线程返回值
思路
和老师的模板几乎差不多,思路见注释。
这边需要注意的是类型转换,还有传的参数,os的参数着实有点多。
代码
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#define NR_TOTAL 300000//round count
#define NR_CPU 200//thread num
#define NR_SIZE (NR_TOTAL/NR_CPU)//one compute
double PI;
//parameter needed
//range
struct parameter{
int start;
int end;
};
//sum computed
struct result{
double sum;
};
void *compute(void *arg)
{
//receive parameter and switch the type
struct parameter *param=(struct param *)arg;
struct result *result;
double output;
double j;
for(int i=param->start;i<param->end;i++)
{
j=i;
if(i%2==0)
output-=1/(2*j-1);
else
output+=1/(2*j-1);
}
//switch the type and return the result
result=malloc(sizeof(struct result));
result->sum=output;
}
int main()
{
//open threads
pthread_t workers[NR_CPU];
struct parameter params[NR_CPU];
//allocate parameters
for(int i=0;i<NR_CPU;i++)
{
struct parameter *param;
param=¶ms[i];
//compute start from 1
param->start=i*NR_SIZE+1;
param->end=(i+1)*NR_SIZE+1;
//create a child thread
pthread_create(&workers[i],NULL,compute,param);
}
//wait child thread
double output=0;
for(int i=0;i<NR_CPU;i++)
{
struct result *result;
//return result through join function
pthread_join(workers[i],(void **)&result);
output+=result->sum;
free(result);
}
PI=4*output;
printf("PI = %f\n",PI);
return 0;
}
job7/sort.c: 多线程排序
- 主线程创建两个辅助线程
- 辅助线程1使用选择排序算法对数组的前半部分排序
- 辅助线程2使用选择排序算法对数组的后半部分排序
- 主线程等待辅助线程运行結束后,使用归并排序算法归并子线程的计算结果
- 本题要求 1: 使用线程参数,消除程序中的代码重复
需要注意一下,参数中的array是指针,在每一个线程中做处理的时候,就等于对array进行了排序处理,这样的话,到最后归并的时候就是前后两段有序数组了
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
int array[10]={41,67,34,58,69,24,78,58,62,64};
int sorted[10];
#define NR_TOTAL 10//round count
#define NR_CPU 2//thread num
#define NR_SIZE (NR_TOTAL/NR_CPU)//one compute
struct parameter {
int *array;
int start;
int end;
};
void *sort(void *arg)
{
//receive parameter and switch the type
struct parameter *param=(struct param *)arg;
int tmp;
int min;
for (int i = param->start; i < param->end; i++){
min = i;
for(int j = i+1 ; j < param->end ; j++){
if(param->array[min] > param->array[j])
min = j;
}
tmp = param->array[i];
param->array[i] = param->array[min];
param->array[min] = tmp;
}
return 0;
}
void Merge(int *array){
int i = 0 , j = NR_TOTAL/2 , k = 0;
while(i < NR_TOTAL/2 && j < NR_TOTAL){
if(array[i] < array[j])
sorted[k++]=array[i++];
else
sorted[k++]=array[j++];
}
while(i<NR_TOTAL/2)
sorted[k++]=array[i++];
while(j<NR_TOTAL)
sorted[k++]=array[j++];
}
int main()
{
//open threads
pthread_t workers[NR_CPU];
struct parameter params[NR_CPU];
//allocate parameters
struct parameter *param;
for (int i = 0; i < NR_CPU; i++) {
param = ¶ms[i];
param->array = array;
param->start=i*NR_SIZE+1;
param->end=(i+1)*NR_SIZE+1;
//create a child thread
pthread_create(&workers[i], NULL, sort, param);
}
for (int i = 0; i < NR_CPU; i++) {
pthread_join(workers[i], NULL);
}
Merge(param->array);
for(int i=0;i<NR_TOTAL;i++)printf("%d ",sorted[i]);
printf("\n");
return 0;
}