多线程排序-v33-多进程-管道通信
2022/7/14 5:20:31
本文主要是介绍多线程排序-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-多进程-管道通信的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-15JavaMailSender是什么,怎么使用?-icode9专业技术文章分享
- 2024-11-15JWT 用户校验学习:从入门到实践
- 2024-11-15Nest学习:新手入门全面指南
- 2024-11-15RestfulAPI学习:新手入门指南
- 2024-11-15Server Component学习:入门教程与实践指南
- 2024-11-15动态路由入门:新手必读指南
- 2024-11-15JWT 用户校验入门:轻松掌握JWT认证基础
- 2024-11-15Nest后端开发入门指南
- 2024-11-15Nest后端开发入门教程
- 2024-11-15RestfulAPI入门:新手快速上手指南