Загрузка данных


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

//каналы передачи: 0 читать, 1 писать
static int from_root[2];//родитель ->потомок
static int to_root[2];//потомок -> родитель

static double local_function(double *a, size_t n, int k, int p)//k - текущий процесс(0 - родитель, остальные малыши - потомки), p - кол-во процессоров
{
    size_t i1 = k*n/p;//старт
    size_t i2 = (k+1)*n/p;//финиш
    size_t i;
    double res = 0;

    for (i = i1; i < i2; i++) {
        res+=a[i];
    }
    return res;//частичная сумма от потомка
}

static void process_function(double *a, size_t n, int k, int p)
{
    char byte;//отклик от родителя
    double res = local_function(a, n, k, p);
    if (read(from_root[0], &byte, 1) != 1) {
        fprintf(stderr, "Error reading process %d, pid = %d\n", k, getpid());
        return;
    }

    if (write(to_root[1], &res, sizeof(double))!= sizeof(double)) {
        fprintf(stderr, "Error writing in process %d, pid = %d\n", k, getpid());
        return;
    }
}

int main(int argc, char *argv[]) {
    pid_t pid;
    int p;
    size_t n;
    size_t i;
    double *a;
    int k;
    double res;
    double total;
    char byte;
    if (argc != 3 || sscanf(argv[1], "%d", &p) != 1|| sscanf(argv[2], "%zu", &n) != 1|| p < 1) {
        printf("Usage: %s p n\n", argv[0]);
        return 1;
    }
    if (n == 0) {
        printf("Res = 0\n");
        return 0;
    }
    a = malloc(n * sizeof(double));
    if (!a) {
        perror("malloc");
        return 1;
    }
//чтобы не суммировать мусор
    for (i = 0; i < n; i++) {
        a[i] = 1.0;
    }
//создаем каналы
    if (pipe(from_root) == -1|| pipe(to_root) == -1) {
        perror("pipe");
        return 2;
    }
    //создание потомков
    for (k = 1; k < p; k++) {
        pid = fork();
        if (pid == -1){
            perror("fork");
            abort();
        }
        if (pid == 0) {//потомки
            close(from_root[1]);
            close(to_root[0]);
            process_function(a,n,k,p);
            close(from_root[0]);
            close(to_root[1]);
            free(a);
            return 0; //клон завершен
        }
    }

    close(from_root[0]);
    close(to_root[1]);
    total = local_function(a,n,0,p);

    for (k = 1; k < p; k++) {
        byte = (char)k;
        if (write(from_root[1], &byte, 1)!= 1) {
            perror("write to child");
            break;
        }
        if (read(to_root[0], &res, sizeof(double))!= sizeof(double)) {
            perror("read from child");
            break;
        }
        total+=res;
    }
    close(from_root[1]);
    close(to_root[0]);

    for (k = 1; k < p; k++) {
        wait(NULL);
    }//ждем завершения всех детишек

    free(a);
    printf("Res = %f\n", total);
    return 0;
}