You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用POSIX创建两个子进程分配任务,计算前20个数的平方?

POSIX多进程拆分任务实现:计算前20个自然数平方并合并排序

核心思路

  • 用**管道(Pipe)**实现父子进程间的通信,每个子进程对应一个管道传递计算结果
  • 父进程创建两个子进程:Son_1处理1-20的奇数平方,Son_2处理1-20的偶数平方
  • 子进程完成计算后将结果写入管道并退出;父进程等待两个子进程终止后,读取所有结果并排序输出

完整代码实现

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#define MAX_NUM 20

// 冒泡排序:适合初学者理解的简单排序实现
void sort(int arr[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (arr[j] > arr[j+1]) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

int main() {
    int pipe_odd[2], pipe_even[2];
    pid_t pid_son1, pid_son2;
    int results[MAX_NUM];
    int count = 0;

    // 创建两个管道:分别用于奇数、偶数结果的传递
    if (pipe(pipe_odd) == -1 || pipe(pipe_even) == -1) {
        perror("管道创建失败");
        exit(EXIT_FAILURE);
    }

    // 创建Son_1:处理奇数
    pid_son1 = fork();
    if (pid_son1 == -1) {
        perror("创建Son_1失败");
        exit(EXIT_FAILURE);
    } else if (pid_son1 == 0) {
        // 子进程关闭无关管道端,只保留奇数管道的写端
        close(pipe_odd[0]);
        close(pipe_even[0]);
        close(pipe_even[1]);

        // 计算奇数平方并写入管道
        for (int i = 1; i <= MAX_NUM; i += 2) {
            int square = i * i;
            write(pipe_odd[1], &square, sizeof(square));
        }

        close(pipe_odd[1]);
        exit(EXIT_SUCCESS);
    }

    // 创建Son_2:处理偶数
    pid_son2 = fork();
    if (pid_son2 == -1) {
        perror("创建Son_2失败");
        exit(EXIT_FAILURE);
    } else if (pid_son2 == 0) {
        // 子进程关闭无关管道端,只保留偶数管道的写端
        close(pipe_odd[0]);
        close(pipe_odd[1]);
        close(pipe_even[0]);

        // 计算偶数平方并写入管道
        for (int i = 2; i <= MAX_NUM; i += 2) {
            int square = i * i;
            write(pipe_even[1], &square, sizeof(square));
        }

        close(pipe_even[1]);
        exit(EXIT_SUCCESS);
    }

    // 父进程操作:关闭管道写端,只保留读端
    close(pipe_odd[1]);
    close(pipe_even[1]);

    // 等待两个子进程完全终止
    wait(NULL);
    wait(NULL);

    // 读取奇数平方结果
    int num;
    while (read(pipe_odd[0], &num, sizeof(num)) > 0) {
        results[count++] = num;
    }

    // 读取偶数平方结果
    while (read(pipe_even[0], &num, sizeof(num)) > 0) {
        results[count++] = num;
    }

    // 关闭管道读端
    close(pipe_odd[0]);
    close(pipe_even[0]);

    // 排序结果
    sort(results, count);

    // 输出最终结果
    printf("排序后的前20个自然数平方:\n");
    for (int i = 0; i < count; i++) {
        printf("%d ", results[i]);
    }
    printf("\n");

    return EXIT_SUCCESS;
}

关键细节解释

  • 管道机制:pipe()创建的管道是半双工的,每个管道有读端(索引0)和写端(索引1),父子进程通过管道直接传递整数数据,无需格式化字符串
  • 进程创建:fork()复制当前进程,返回0代表子进程,返回正整数是子进程PID(父进程持有),返回-1则创建失败
  • 管道端管理:必须关闭无关的管道端,否则会导致read()函数一直阻塞,等待不存在的写端数据
  • 等待子进程:wait(NULL)会阻塞父进程,直到一个子进程结束,调用两次确保两个子进程都完成计算
  • 排序替换:如果想使用更高效的排序,可以替换为标准库的qsort()函数,只需添加比较函数:
    int compare(const void *a, const void *b) {
        return (*(int*)a - *(int*)b);
    }
    
    然后调用qsort(results, count, sizeof(int), compare);即可

编译与运行

编译命令:

gcc -o square_process square_process.c

运行后输出:

排序后的前20个自然数平方:
1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400 

内容的提问来源于stack exchange,提问作者Mario Serna León

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 11:22:41