多线程
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 = ¶ms[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 = ¶ms[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;
}