Задержка перед выполнением моих дочерних процессов? - PullRequest
0 голосов
/ 17 октября 2019

У меня есть относительно мощный персональный компьютер, на котором я выполняю следующее.

Хорошо, поэтому я пытаюсь отсортировать 14,301 фрагментов данных с помощью одной программы, написанной на языке C. Это завершает задачуменее чем за секунду. Я показал это своему профессору, который говорит, что это невозможно (должно занять больше времени). Я не знаю, как это объяснить. Когда я увеличиваю набор данных до 60000, это занимает 10 секунд.

В любом случае, мне также поручено создать программу, которая сортирует и может создавать дочерние процессы с использованием fork и exec, сортировать части большого набора данных, а затем объединять все данные вместе. Когда я это сделал, я создал отладку для отладки и выяснил, что вызывает выполнение этой задачи за 10 секунд. То, что в итоге происходит, - это то, что дочерние процессы не выполняются примерно через 10 секунд (или, по крайней мере, печать не вызывается до 10 секунд спустя, после чего происходят все дочерние печати). Затем дочерние процессы запускаются, завершаются и объединяются в течение секунды.

Когда я отслеживаю этот код с помощью Ps -ax, в моем списке процессов отображается только один процесс (a.out). Я не вижу дочерних процессов.

Все это очень запутанно.

Вот код моего основного файла. Мои execs вызывают файл .out, который сортирует часть списка, а затем записывает их обратно в файл, который родитель читает и объединяет

#define DATA_STRING "qbig2.txt"

/* Driver Program
 */

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

void sort(float*, int);
void swap(float*, float*);
void printArray(float*, int);
void printLast5(float*, int);
int getArraySize(char *);
void mergeArrays(float *, float *, float *, float *, float *, int, int);
void readFromCSV(float*, int);
void writeToFile(float*, int, char *);
void readFromChildFile(float*, int, char *);

int main(void) 
{
    int numOfProcesses = 4;
    time_t t;
    int arraySize = getArraySize(DATA_STRING);
    int subArraySize = arraySize/4;
    printf("Array Size: %d, %d\n", arraySize, subArraySize);
    float array[arraySize];
    int i, j;
    float sub1[subArraySize];
    float sub2[subArraySize];
    float sub3[subArraySize];
    float sub4[subArraySize];
    t = time(NULL);
    printf( "Start Time: %s", ctime(&t));
    readFromCSV(array, arraySize);
    sort(array, arraySize);
    //printArray(array, arraySize);
    //scanf("%d", &i);
    int p1 = fork();
    int p2 = fork();

    if (p1 > 0 && p2 > 0)
        {
    for(i=0; i<subArraySize+1; i++)
        {
            sub1[i]=array[i];
        }
        sort(sub1, (subArraySize));
        sleep(2);
//      pid_t waitP = wait(NULL);
        //int waitstatus;
            //wait(&waitstatus);
            //printf("\nI: %d\n", i = WEXITSTATUS(waitstatus));
            printf("\nReading 1...\n");
        readFromChildFile(sub2, subArraySize, "out2.txt");
            printf("Reading 2...\n");
            readFromChildFile(sub3, subArraySize, "out3.txt");
            printf("Reading 3...\n");
            readFromChildFile(sub4, subArraySize, "out4.txt");
        printf("\nMerging...");
        mergeArrays(array, sub1, sub2, sub3, sub4, arraySize, subArraySize);
        printLast5(array, arraySize);
    //  printArray(array, arraySize);
        t = time(NULL);
        printf( "End Time: %s\n", ctime(&t));
    }
    else if (p1==0 && p2>0)//first child!!!
        {
        for(i=0; i<subArraySize; i++)
            sub2[i]=array[i+subArraySize];
        printf("\nChild 1 being written to file...");
        writeToFile(sub2, subArraySize, "sub2.txt");
        printf("\nChild 1 being forked...");
        execv("./cp2.out", NULL);
    }
    else if (p1>0 && p2==0)//second child!!!
    {
        for(i=0; i<subArraySize; i++)
            sub3[i]=array[i+(2*subArraySize)];
        printf("\nChild 2 being written to file...");
        writeToFile(sub3, subArraySize, "sub3.txt");
        printf("\nChild 2 being forked...");
        execv("./cp3.out", NULL);

    }
    else if(p1==0 && p2==0)//third child!!!
    {
        for(i=0; i<subArraySize; i++)
            sub4[i]=array[i+(3*subArraySize)];
        printf("\nChild 3 being written to file...");
        writeToFile(sub4, subArraySize, "sub4.txt");
        printf("\nChild 3 being forked...");
        execv("./cp4.out", NULL);
    }
    else{
    printf("\nBROKEN FORK!\n");
    }   
    return 0;
}

void readFromCSV(float* array, int size){
    FILE *fp = fopen(DATA_STRING, "r");
    if(fp!=NULL)
    {
        char line[2000];
        char* token;
        int i;
        int j=0;
        while(fgets(line, 2000, fp)!=NULL)
        {
            i=0;
            token = strtok(line, ",");
            while(token!=NULL){
                token = strtok(NULL, ",");
                if(i==0){
                    array[j] = atof(token);
                    j=j+1;
                }
                i=i+1;
            }
        }
    }
    fclose(fp);
} 

void readFromChildFile(float* array, int size, char* fileString){
    FILE * f = fopen(fileString, "r");
    for(int i=0; i<size; i++)
    {
            fscanf(f, "%f", &array[i]);
    }
    fclose(f);
}

int getArraySize(char * string){
        int n = 0;

        FILE * f = fopen(string, "r");
        for(char c = getc(f); c!= EOF; c=getc(f))
                if(c=='\n')
        {
                        n = n + 1;
        }
        fclose(f);
        return n;
}

void writeToFile(float * array, int size, char* fileString){
    FILE *f = fopen(fileString, "w+");
    for(int i=0; i<size; i++){
        fprintf(f, "%f\n", array[i]);
    }
    fclose(f);
}

void printArray(float * array, int size)
{
    int count = 0;
    for(int i=0; i<size-1; i++){
        printf(" %f", array[i]);
        count+=1;
        if(count%10==0)
            printf("\n");
    }
}

void printLast5(float* array, int size){
    for(int i=size-15; i<size; i++)
        printf(" %f", array[i]);
}

void swap(float *xp, float *yp){
    float temp = *xp;
    *xp = *yp;
    *yp = temp;
}

void sort(float * array, int size){
    for(int i=0; i<size-1; i++){
        for(int j=0; j<size-i-1; j++)
        {
            if(array[j]>array[j+1])
                swap(&array[j], &array[j+1]);
        }   
    }
}

//rewrite
void mergeArrays(float *array, float *sub1, float *sub2, float *sub3, float *sub4, int size, int subArraySize){
    int i1=0, i2=0, i3=0, i4=0, k=0;

    while(i1<subArraySize && i2<subArraySize && i3<subArraySize && i4<subArraySize)
    {
        if(sub1[i1] <= sub2[i2] && sub1[i1] <= sub3[i3] && sub1[i1] <= sub4[i4])
            array[k++] = sub1[i1++];
        else if(sub2[i2] <= sub1[i1] && sub2[i2] <= sub3[i3] && sub2[i2] <= sub4[i4])
            array[k++] = sub2[i2++];
        else if(sub3[i3] <= sub1[i1] && sub3[i3] <= sub2[i2] && sub3[i3] <= sub4[i4])
            array[k++] = sub3[i3++];
        else if(sub4[i4] <= sub1[i1] && sub4[i4] <= sub2[i2] && sub4[i4] <= sub3[i3])
            array[k++] = sub4[i4++];
    }
    while(i1<subArraySize)
        array[k++]=sub1[i1++];
    while(i2<subArraySize)
        array[k++]=sub2[i2++];
    while(i3<subArraySize)
        array[k++]=sub3[i3++];
    while(i4<subArraySize)
        array[k++]=sub4[i4++];
}
...