【操作系统 实验七】--- 多线程

job7/pi1.c: 使用2个线程根据莱布尼兹级数计算PI

题目

莱布尼兹级数公式: 1 - 1/3 + 1/5 - 1/7 + 1/9 - … = PI/4
主线程创建1个辅助线程
主线程计算级数的前半部分
辅助线程计算级数的后半部分
主线程等待辅助线程运行結束后,将前半部分和后半部分相加

运行结果

END取9999
在这里插入图片描述

代码

#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>


#define  END 9999

//master 1~(end-1)/2        worker (end+1)/2  end
//
double worker_output=0;
void *worker(void *arg)
{
	for(int i=(END+3)/2;i<END;i+=2)
	{
		double num = i;
		if((i+1)%4==0)
		{
		//	printf("-1/%d",i);
			worker_output-=1.0/num;
		}
		else
		{
		//	printf("+1/%d",i);
			worker_output+=1.0/num;
		}
	}
}
double master_output=0;
void master()
{
	for(int i=1;i<=(END-1)/2;i+=2)
	{
		double num = i;
		if((i+1)%4==0)
		{
		//	printf("-1/%d",i);
			master_output-=1.0/num;
		}
		else
		{
		//	printf("+1/%d",i);
			master_output+=1.0/num;
		}
	}
}
int main()
{
	pthread_t worker_tid;
	double total;
	pthread_create(&worker_tid,NULL,worker,NULL);
	master();
	pthread_join(worker_tid,NULL);
	total = master_output + worker_output;
	total*=4;
//	printf("master_output = %f\nworker_output = %f\npi = %f\n",master_output,worker_output,total);
	printf("pi = %f\n",total);
	return 0;
}

总结

了解了线程

job7/pi2.c: 使用N个线程根据莱布尼兹级数计算PI

题目

与上一题类似,但本题更加通用化,能适应N个核心
主线程创建N个辅助线程
每个辅助线程计算一部分任务,并将结果返回
主线程等待N个辅助线程运行结束,将所有辅助线程的结果累加
本题要求 1: 使用线程参数,消除程序中的代码重复
本题要求 2:不能使用全局变量存储线程返回值

运行结果

END取9999
CORE_N 取 10
在这里插入图片描述

代码

#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>


#define  END 9999
#define CORE_N 10

struct param{
	int start;
	int end;
};
struct result{
	double sum;
};
void *compute(void *arg)
{
	struct param *param;
	struct result *result;
	double sum = 0;

	param = (struct param *)arg;

	for(int i=param->start;i<param->end;i++)
	{
		double num = i;
		if(i%2==1)
		{
			if((i+1)%4==0)
			{
			//	printf("-1/%d",i);
				sum-=1.0/num;
			}
			else
			{
			//	printf("+1/%d",i);
				sum+=1.0/num;
			}
		}
	}
	result = malloc(sizeof(struct result));
	result->sum = sum;
	return result;
}

int main()
{
	pthread_t worker_tids[CORE_N];
	struct param params[CORE_N];
	double total=0;
	
	for(int i=0;i<CORE_N;i++)
	{
		struct param *param;
		param = &params[i];
		param -> start = i*END/CORE_N;
		param -> end = (i+1)*END/CORE_N;
		pthread_create(&worker_tids[i],NULL,compute,param);
	}
	
	for(int i=0;i<CORE_N;i++)
	{
		struct result *result;
		pthread_join(worker_tids[i],(void**)&result);
		printf("CPU%d sum = %f\n",i,result->sum);
		total += result->sum;
		free(result);
	}
	total*=4;
	printf("pi = %f\n",total);
	return 0;
}

总结

了解了多线程

job7/sort.c: 多线程排序

题目

主线程创建两个辅助线程
辅助线程1使用选择排序算法对数组的前半部分排序
辅助线程2使用选择排序算法对数组的后半部分排序
主线程等待辅助线程运行結束后,使用归并排序算法归并子线程的计算结果
本题要求 1: 使用线程参数,消除程序中的代码重复

运行结果

在这里插入图片描述

代码

#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
int array[] = {5,3,8,5,1,8,0,6,4,9};

#define NR_TOTAL 10
#define CORE_N 2
int new_array[NR_TOTAL];
struct param{
	int *array;
	int start;
	int end;
};
struct result{
	int *array;
};
void Print(int array[])
{
	for(int i=0;i<NR_TOTAL;i++)
	{
		printf("%d ",array[i]);
	}
	printf("\n");
}
void *compute(void *arg)
{
	struct param *param;
	struct result *result;
	int temp;

	param = (struct param *)arg;

	for(int i=param->start;i<param->end;i++)//select sort
	{
		for(int j=i;j<param->end;j++)
		{
			if(param->array[i]>param->array[j])
			{
				temp = param->array[i];
				param->array[i] = param->array[j];
				param->array[j] = temp;
			}
		}
	}
	result = malloc(sizeof(struct result));
	result->array = param->array;
	return result;
}
void merge(int array[])
{
	int n=0 ,m=NR_TOTAL/CORE_N;
	//int new_array[NR_TOTAL];
	int i;
	for(i=0;n<NR_TOTAL/CORE_N&&m<NR_TOTAL;i++)
	{
		if(array[n]>array[m])
		{
			new_array[i] = array[m++];
		}
		else
		{
			new_array[i] = array[n++];
		}
	}
	if(n<NR_TOTAL/CORE_N)
	{
		while(i<NR_TOTAL)
		{
			new_array[i++] = array[n++];
		}
	}
	if(m<NR_TOTAL)
	{
		while(i<NR_TOTAL)
		{
			new_array[i++] = array[m++];
		}
	}
}
int main()
{
	pthread_t worker_tids[CORE_N];
	struct param params[CORE_N];
	double total=0;
	Print(array);	
	for(int i=0;i<CORE_N;i++)
	{
		sleep(1);
		struct param *param;
		param = &params[i];
		param -> array = array;
		param -> start = i*NR_TOTAL/CORE_N;
		param -> end = (i+1)*NR_TOTAL/CORE_N;
		pthread_create(&worker_tids[i],NULL,compute,param);
	}
	
	for(int i=0;i<CORE_N;i++)
	{
		struct result *result;
		pthread_join(worker_tids[i],(void**)&result);
		//array = result->array;
		Print(result->array);
		memcpy(array,result->array,sizeof(int)*NR_TOTAL);
		free(result);
	}
	merge(array);
	memcpy(array,new_array,sizeof(int)*NR_TOTAL);
	Print(array);
	return 0;
}

总结

了解了多线程,复习了归并排序

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值