fseek ftell чтение того же ввода

Я пытаюсь заставить свою программу читать по одной строке для каждого ребенка (каждая строка содержит один int). Каждый раз, когда я выполняю это чтение, он продолжает читать первую строку.

Вот основа моего кода.

void forkChildren (int nChildren) {
int i;
int size;
int sum = 0;
int tell = 0;
pid_t pid;
for (i = 0; i < nChildren; i++) {
    pid = fork();
    if (pid == -1) {
        /* error handling here, if needed */
        return;
    }
    if (pid == 0) {
        char data[10];
        FILE * file1;
        file1 = fopen("numbers.dat", "r");
        fseek(file1, tell, SEEK_SET);
        fgets(data, 10, file1);
        //fseek(file1, tell, SEEK_SET);
        tell += strlen(data); 
        printf("%d ", tell);
        sum = atoi(data);
        printf("Sum is: %d \n", sum);
        sleep (5);
        return;
    }

person mschlesinger19    schedule 09.12.2013    source источник
comment
Вы ищете одно и то же смещение от начала файла во всех дочерних процессах. Если это не то, что вы хотите, скажите нам, что вы хотите.   -  person Fred    schedule 09.12.2013
comment
Даже если подумать, что я увеличиваю теллс каждый раз, когда выполняю чтение? Или это только увеличивает подсказку для этого ребенка?   -  person mschlesinger19    schedule 09.12.2013
comment
Это только увеличивает Tell для каждого потомка, потому что (a) каждый потомок работает с другим (уникальным) файловым дескриптором и (b) переменная Tell является отдельной копией в каждом потомке. Вы можете добавить, чтобы сказать в одном, и другие (ни родитель) никогда не узнают разницу.   -  person Duck    schedule 09.12.2013
comment
Итак, хм, вы используете буферизованный ввод-вывод уровня 3 для одного и того же файла, поскольку несколько дочерних процессов манипулируют одним и тем же файлом? Почему бы вам (а) не использовать каналы, чтобы избежать прохождения через файловую систему, или (б) не использовать файл для каждого ребенка? Каждый дочерний элемент наследует свою собственную частную копию tell, но это означает, что все они разделяют значение по умолчанию 0 от родителя.   -  person kfsone    schedule 09.12.2013


Ответы (1)


После разветвления у каждого потомка будет своя печатная плата. Поскольку вы открываете файл после разветвления, каждый потомок имеет свой собственный отдельный файловый дескриптор, смещение и т. д.
Если вы хотите, чтобы дочерние процессы использовали один и тот же файловый дескриптор и смещение, они должны указывают на тот же файловый дескриптор, который создает ядро. Для этого вам нужно открыть файл перед разветвлением.
Подробнее читайте здесь.

Дочерний процесс наследует копии родительского набора дескрипторов открытых файлов...

В своем коде вы пытаетесь отслеживать позицию в файле с помощью int tell, но эта переменная не используется совместно дочерними процессами. Вместо этого используйте общий файловый дескриптор, и ядро ​​будет отслеживать смещение за вас.

person EyalAr    schedule 09.12.2013
comment
Спасибо! я попробую - person mschlesinger19; 09.12.2013
comment
Что произойдет, если я захочу пропустить строку, используя этот процесс? - person mschlesinger19; 09.12.2013
comment
Как только вы разветвляете, вы теряете синхронность между дочерними процессами, так как теперь синхронизация контролируется ядром. Это означает, что операции с общими ресурсами несколько непредсказуемы. Вы можете пропускать строки, если хотите, но трудно гарантировать, когда (по отношению к другим детям) это произойдет. - person EyalAr; 09.12.2013