操作系统实践(七)

  实验到此,正式进入线程部分。本次实验课的主要内容是线程的建立(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;
}

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

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

Guess you like

Origin blog.csdn.net/gls_nuaa/article/details/117392161