【操作系统实验笔记2】

多线程

1.1 创建线程

int pthread_create(pthread_t *tid, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
  • 功能
    创建一个线程
    新线程从start_routine开始执行
    新线程的ID保存在tid指向的位置

1.2 线程参数

创建线程时可以为线程入口函数提供参数

void *arg = "hello";
pthread_create(&tid, NULL, start_routine, arg);

线程入口函数接收类型为void *类型的参数
void *start_routine(void *arg)
{
    char *string = (char *)arg;
    puts(string); // 输出hello
}

1.3 等待线程

#include <pthread.h>
int pthread_join(pthread_t tid, void **result);

2.1作业 pi1.c

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

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

//int array[] = {1, 1, 1, 2, 2, 2};
#define MAX 65535
//#define NUMBER 6 

float worker_output=0.0;

void *worker(void *arg)
{
    int i;
    float add1=MAX/2.0;
    for (i =MAX/2; i < MAX; i++)
    {
        if(i%2==0)
        {
        worker_output+=1.0/add1;
        }
        else{
            worker_output-=1.0/add1;
        }
        
        add1=add1+2.0;
    }
    return NULL;
}

float master_output=0.0;

void master()
{
    int i;
    float add=1.0;
    for (i =0; i < MAX/2; i++)
    {
        if(i%2==0)
        {
   //     printf("%d\n",1.0/add);
      //            puts("kkk");
         master_output+=1.0/add;
        }
        else{
     //    printf("%d\n",master_output);
            master_output-=1.0/add;
        }
  
      // puts("??");
        add=add+2.0;
        //printf("%d\n",add);
    }
        
}

int main()
{ 
    pthread_t worker_tid;
    float total;

    pthread_create(&worker_tid, NULL, worker, NULL);
    master(); 
    pthread_join(worker_tid, NULL);
    total = master_output + worker_output;
    printf("master_output = %f, worker_output = %f, total = %f\n", master_output, worker_output, total);
    return 0;
}

2.2 作业pi2.c

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

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

//int array[] = {1, 1, 1, 2, 2, 2};
#define NR_TOTAL 65535
#define NR_CPU 16
#define NR_CHILD (NR_TOTAL/NR_CPU)

struct param {
    //int *array;
    int start;
    int end;
};

struct result {
    float sum;
};

void *compute(void *arg)
{
    struct param *param;
    struct result *result;
    float sum = 0.0;
    int i;
    float add;
    param = (struct param *)arg;
    for (i = param->start; i < param->end; i++)
    {
        add=i*2.0+1.0;
        if(i%2==0)
        sum += 1.0/add;
        else{
            sum-=1.0/add;
        }
        add=add+2.0;
    }
        

    result = malloc(sizeof(struct result));
    result->sum = sum;
    return result;
}

int main()
{ 
    pthread_t workers[NR_CPU];
    struct param params[NR_CPU]; 
    int i;

    for (i = 0; i < NR_CPU; i++) {
        struct param *param;
        param = &params[i];
        //param->array = array;
        param->start = i * NR_CHILD; 
        param->end = (i + 1) * NR_CHILD;
        pthread_create(&workers[i], NULL, compute, param);
    }

    float sum = 0.0;
    for (i = 0; i < NR_CPU; i++) {
        struct result *result;
        pthread_join(workers[i], (void **)&result);
        sum += result->sum;
        free(result);
    }

    printf("sum = %f\n", sum);
    return 0;
}

2.3 作业sort.c

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

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include<stdio.h>
#define ArrLen 20
int array[] = {4,53,71,2,3,48,12,35};
#define NR_TOTAL 8
#define NR_CPU 2
#define NR_CHILD (NR_TOTAL/NR_CPU)
//#define NUMBER 9
struct param {
    int *array;
    int start;
    int end;
};

struct result {
    float sum;
};

void printList(int arr[], int len) {
	int i;
	for (i = 0; i < len; i++) {
		printf("%d\t", arr[i]);
	}
}
//归并算法
void merge(int arr[], int start, int mid, int end) {
	int result[ArrLen];
	int k = 0;
	int i = start;
	int j = mid + 1;
	while (i <= mid && j <= end) {
		if (arr[i] < arr[j]){
			result[k++] = arr[i++];
        }
		else{
			result[k++] = arr[j++];
        }
	}
	if (i == mid + 1) {
		while(j <= end)
			result[k++] = arr[j++];
	}
	if (j == end + 1) {
		while (i <= mid)
			result[k++] = arr[i++];
	}
	for (j = 0, i = start ; j < k; i++, j++) {
		arr[i] = result[j];
	}
}
 
void mergeSort(int arr[], int start, int end) {
	if (start >= end)
		return;
	int mid = ( start + end ) / 2;
	mergeSort(arr, start, mid);
	mergeSort(arr, mid + 1, end);
	merge(arr, start, mid, end);
}

void *compute(void *arg)
{
    struct param *param;
    //struct result *result;
    float sum = 0.0;
    int i;
    float add;
    int t;
    int j;
    param = (struct param *)arg;
    printf("%d\n",param->start);
    printf("%d\n",param->end);
    puts("kkk");
    for (i = param->start; i < param->end-1; i++)
    {
        for (j =i+1; j < param->end; j++)
            if(array[i]>array[j])    //如果前一个数比后一个数大,则利用中间变量t实现两值互换
            {
                t=array[i];
                array[i]=array[j];
                array[j]=t;
            }
    }

 printList(array,8);
 puts("kkk");

    //result = malloc(sizeof(struct result));
    //result->sum = sum;
    return NULL;
}

int main()
{ 
    pthread_t workers[NR_CPU];
    struct param params[NR_CPU]; 
    int i;

    for (i = 0; i < NR_CPU; i++) {
        struct param *param;
        param = &params[i];
        param->array = array;
        param->start =i*NR_CHILD;
        param->end = (i + 1) * NR_CHILD;
        pthread_create(&workers[i], NULL, compute, param);
    }

    //float sum = 0.0;
    for (i = 0; i < NR_CPU; i++) {
       // struct result *result;
        pthread_join(workers[i], NULL);
        //sum += result->sum;
       // free(result);
    }
merge(array, 0, 3, 7);
    //mergeSort(array, 0, 7);
    printList(array,NR_TOTAL);
   // printf("sum = %f\n", sum);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值