操作系统实践(七)

  实验到此,正式进入线程部分。本次实验课的主要内容是线程的建立(pthread_create)和同步(pthread_join)。下面对内容进行下介绍:

线程建立

在这里插入图片描述在这里插入图片描述
  为什么要有一个线程参数呢? 在多线程情况下,每个线程执行的任务差不多。但是输入参数不同。不使用线程参数的话,要为每一个线程写一个执行函数。这样代码重复性很大,通过设置参数,提供不同的参数来实现代码复用。根据需要,三种类型可选。

线程等待

在这里插入图片描述在这里插入图片描述  这里解释下为什么要有线程的返回值:如果不设置返回值的话就要用全局变量去保存每个线程的结果,不太方便。直接用返回值存储,比较方便。

  作业的话就是对于线程的创建同步的使用,题目如下:

注意:对于线程编译的时候不能简单的gcc pi1.c,否则会报错,像这样:
在这里插入图片描述

必须:gcc pi1.c -lpthread
在这里插入图片描述
  代码如下:

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

#define NUMBER 30000

double son_out = 0;
double father_out = 0;

int t_son = 1;
int t_father = 1;

void *son(void *arg) {
	for (int i=NUMBER/2; i<NUMBER; i++) {
		son_out += t_son*(1.0/(2*i-1));
		t_son = -1 * t_son;
	}
}

void father() {
	for (int i=1; i<NUMBER/2; i++) {
		father_out += t_father*(1.0/(2*i-1));
		t_father = -1 * t_father;
	}
}

int main() {
	pthread_t son_id;
	pthread_create(&son_id, NULL, son, NULL);
	father();
	pthread_join(son_id, NULL);
	double total = 0;
	total = son_out + father_out;
	printf("the ending is %lf\n", 4*total);
	return 0;
}

在这里插入图片描述  代码如下:

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

#define NUMBER 30000
#define CPU_NUM 2
#define CHILD (NUMBER/CPU_NUM)

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; // 参数都是void *,要转成对应的类型
	for (int i=param->start; i<param->end; i++) {
		if (i % 2 == 0) {
			sum += 1.0/(2*i+1);
		}
		else {
			sum -= 1.0/(2*i+1);
		}
	}
	result  = malloc(sizeof(struct result));
	result->sum = sum;
	return result;
}

int main() {
	pthread_t son[CPU_NUM];	
	struct param params[CPU_NUM]; // 必须要申请,否则段错误
	for (int i=0; i<CPU_NUM; i++) {
		// param不可作为临时变量,都必须是params的地址
		struct param *param; 
		param = &params[i];
		param->start = i*CHILD;
		param->end = (i+1)*CHILD;
		pthread_create(&son[i], NULL, compute, param);
	}
	double sum = 0;
	for (int i=0; i<CPU_NUM; i++) {
		struct result *result;
		pthread_join(son[i], (void **)&result);
		sum += result->sum;
		free(result); // 用完一定要释放
	}
	printf("ending is %lf\n", 4*sum);
	return 0;
}

  两个代码经过检验,结果都是正确的(在误差允许范围内)!

  又一次实验课,继续加油吧!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值