多线程排序-v33-多进程-管道通信
作者:互联网
makefile
v33:v33.o
gcc -o v33 v33.o -lm -lpthread
v33.o:v33.c
gcc -c v33.c
.PHONY:clean
clean:
-rm v33
-rm *.o
-rm *.txt
v33.c
// 多线程排序-多进程-管道通信-V33
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/resource.h>
#include <stdlib.h>
#include <unistd.h>
#define SIZE 16
struct data_size
{
int size;
int *data;
};
struct data_info
{
int size;
int *data;
};
// 注意多进程结构体的内容
struct fork_info
{
struct data_size array;
struct data_info *bins;
int status;
pid_t npid;
int pipefd[2]; // pipe管道创建的两个文件描述符,读和写
};
// 申请内存空间
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 data_size array)
{
srand(1);
for (int i = 0; i < array.size; i++)
{
array.data[i] = rand() % 1000;
}
}
// 打印数据
void print_data(struct data_size array, char *txt)
{
FILE *fp;
char num_str[4] = {""};
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(struct data_size array, struct data_info bins[])
{
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;
}
}
}
// 排序
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 data_size 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 data_size 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 data_size array;
struct data_info bins[4];
struct fork_info forks[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);
}
// 初始数据
produce_data(array);
// 打印数据
print_data(array, "original.txt");
// 分配数据到缓存数据区
split_data(array, bins);
// 计算总数据量
int sum = 0;
for (int i = 0; i < 4; i++)
{
sum += bins[i].size;
}
printf("Size=%d.\n", sum);
// 多进程
for (int i = 0; i < 4; i++)
{
forks[i].bins = &bins[i]; // 注意使用取地址符
if (pipe(forks[i].pipefd) < 0) // 创建管道文件描述符,读和写
{
perror("Error pipe");
exit(EXIT_FAILURE);
}
forks[i].npid = fork(); // 创建子进程
if (forks[i].npid < 0) // 创建子进程失败
{
perror("Error fork");
exit(EXIT_FAILURE);
}
else if (forks[i].npid == 0) // 子进程
{
insertion(*forks[i].bins); // 多进程的排序,使用的是带星号
close(forks[i].pipefd[0]);
write(forks[i].pipefd[1], &forks[i].bins->data[0], sizeof(int) * forks[i].bins->size);
close(forks[i].pipefd[1]);
_exit(EXIT_SUCCESS);
}
else // 父进程
{
close(forks[i].pipefd[1]);
int pos = 0;
int size = 0;
while ((size = read(forks[i].pipefd[0], forks[i].bins->data + pos / sizeof(int), sizeof(int) * forks[i].bins->size)) > 0)
{
printf("child[%d] pipe pos=%d size=%d\n", i, pos, size);
pos += size;
};
close(forks[i].pipefd[0]);
}
}
// 进程同步
for (int i = 0; i < 4; i++)
{
waitpid(forks[i].npid, &forks[i].status, 0);
}
// 转移数据从缓存区到原始数据区
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);
}
标签:v33,int,排序,array,多线程,data,forks,bins,size 来源: https://www.cnblogs.com/starc/p/16473861.html