操作系统实践 job7

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=&params[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 = &params[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;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值