源码
// 拆分数据使用多线程-V11.c
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>
#define SIZE 16
// 原始数据结构体
struct size_data
{
int size;
int *data;
};
// 多线程缓存的数据结构体
struct data_info
{
int size;
int *data;
};
// 多线程结构体
struct thread_info
{
struct size_data array;
struct data_info *bins;
};
// 多线程互斥锁
pthread_mutex_t lock;
// 分配内存空间
int *allocate(int size)
{
int *space;
space = (int *)calloc(size, sizeof(int));
if (space == NULL)
{
perror("Error allocate");
exit(EXIT_FAILURE);
}
return space;
}
// 生成随机数据
void produce_data(struct size_data array)
{
srand(1);
for (int i = 0; i < array.size; i++)
{
array.data[i] = rand() % 1000;
}
}
// 打印数据
void print_data(struct size_data array, char * txt)
{
FILE *fp;
char num_str[4] = {0};
fp = fopen(txt, "w");
if (fp == NULL)
{
perror("Error print data");
exit(EXIT_FAILURE);
}
for (int i = 0; i < array.size; i++)
{
sprintf(num_str, "%d", array.data[i]);
fwrite(num_str, sizeof(num_str), 1, fp);
fputc('\n', fp);
}
fclose(fp);
}
// 划分数据给各个线程
void *split_data(void *param)
{
struct thread_info args = *(struct thread_info *)param;
struct size_data array = args.array;
struct data_info * bins = args.bins;
pthread_mutex_lock(&lock);
for (int i = 0; i < array.size; i++)
{
int number = array.data[i];
if (number < 250)
{
bins[0].data[bins[0].size++] = number;
}
else if (number < 500)
{
bins[1].data[bins[1].size++] = number;
}
else if (number < 750)
{
bins[2].data[bins[2].size++] = number;
}
else
{
bins[3].data[bins[3].size++] = number;
}
}
pthread_mutex_unlock(&lock);
printf("over thread ID:%d.\n", pthread_self());
}
// 排序算法
void insertion(struct data_info bin)
{
for (int i = 1; i < bin.size; i++)
{
for (int j = i; j > 0; j--)
{
if (bin.data[j - 1] > bin.data[j])
{
int temp;
temp = bin.data[j];
bin.data[j] = bin.data[j - 1];
bin.data[j - 1] = temp;
}
else
{
break;
}
}
}
}
// 将数据从线程缓存区复制到原始数据区
void move_back(struct size_data array, struct data_info bins[])
{
for (int bin = 0; bin < 4; bin++)
{
for (int i = 0; i < bins[bin].size; i++)
{
*array.data++ = bins[bin].data[i];
}
}
}
// 判断是否排序正确
bool is_sorted(struct size_data array)
{
bool sorted = true;
for (int i = 0; i < array.size - 1; i++)
{
if (array.data[i] > array.data[i + 1])
sorted = false;
}
return sorted;
}
// 主函数
int main(int argc, char * argv[])
{
// 初始化参数
struct size_data array;
struct data_info bins[4];
struct thread_info threads[4];
pthread_t thread_type[4];
// 根据输入参数,设置数据量级
if (argc < 2)
{
array.size = SIZE;
}
else
{
array.size = pow(2, atoi(argv[1]));
}
// 分配内存空间
array.data = allocate(array.size);
for (int i = 0; i < 4; i++)
{
bins[i].size = 0;
bins[i].data = allocate(array.size); // 为什么用array.size?
}
// 随机生成数据
produce_data(array);
// 打印数据
print_data(array, "orignal.txt");
// 分配多线程任务
int *start_data = array.data;
pthread_mutex_init(&lock, NULL);
for (int i = 0; i < 4; i++)
{
threads[i].array.size = array.size / 4;
threads[i].array.data = start_data;
start_data += array.size / 4;
threads[i].bins = bins;
if (pthread_create(&thread_type[i], NULL, split_data, (void *)&threads[i]))
{
perror("Error creating thread.\n");
exit(EXIT_FAILURE);
}
}
// 多线程同步
for (int i = 0; i < 4; i++)
{
pthread_join(thread_type[i], NULL); // 不能加&,会卡主
}
// 销毁线程同步锁
pthread_mutex_destroy(&lock);
// 计算各个线程数据量的总数
int sum = 0;
for (int i = 0; i < 4; i++)
{
sum += bins[i].size;
}
printf("Total size:%d.\n", sum);
// 合并排序
for (int i = 0; i < 4; i++)
{
insertion(bins[i]);
}
// 数据从线程缓存,复制到原始数组内存空间
move_back(array, bins);
// 打印数据
print_data(array, "insertion.txt");
// 判断是否排序完成
printf(is_sorted(array) ? "sorted\n":"not sorted\n");
// 释放内存空间
free(array.data);
for (int i = 0; i < 4; i++)
{
free(bins[i].data); // 这个内存空间的作用是?
}
exit(EXIT_SUCCESS);
}
makefile
v11:v11.o
gcc -o v11 v11.o -lm -lpthread
v11.0:v11.c
gcc -c v11.c
.PHONY:clean
clean:
-rm *.o
-rm v11
-rm *.txt