Operações de arquivos e processos

1

É possível que dois processos diferentes (pai e filho) possam ver o mesmo arquivo de texto e manipulá-lo?

Eu consegui isso, mas tive que abrir o arquivo em ambos os processos usando fopen (). Minha expectativa é que um dos processos abra o arquivo e o outro possa vê-lo e manipulá-lo.

    
por Goktug 04.03.2018 / 12:14

2 respostas

1

De o manual fork(2) no meu sistema OpenBSD (minha ênfase):

The child process has its own copy of the parent's descriptors. These descriptors reference the same underlying objects, so that, for instance, file pointers in file objects are shared between the child and the parent, so that an lseek(2) on a descriptor in the child process can affect a subsequent read(2) or write(2) by the parent. This descriptor copying is also used by the shell to establish standard input and output for newly created processes as well as to set up pipes.

Isso significa que, se você abrir um arquivo no processo pai antes de bifurcar o filho, ambos os processos terão o mesmo arquivo aberto. No entanto, se a criança ler o arquivo, o ponteiro de arquivo do pai também será movido.

Para acessar um arquivo em ambos os processos independentemente , você precisa abrir o arquivo em ambos os processos separadamente.

Se você abrir um arquivo no pai após a chamada para fork() , ele não será aberto no processo filho e vice-versa.

    
por 04.03.2018 / 12:20
0

E aqui está um código de exemplo que faz exatamente isso.

#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

char buf[8];

int main(int argc, char *argv[])
{
    int ch, fd[2], rv;

    signal(SIGPIPE, SIG_IGN);
    pipe(fd);

    switch (fork()) {
    case -1:
        err(1, "could not fork");
    case 0:                    // child
        rv = lseek(STDIN_FILENO, -7, SEEK_END);
        if (rv == -1) err(1, "could not seek");
        sleep(3);
        close(fd[1]);
        break;
    default:                   // parent
        close(fd[1]);
        read(fd[0], &ch, 1);
        read(STDIN_FILENO, buf, 7);
        printf("read '%s'\n", buf);
    }
    return 0;
}

o que está acontecendo é que o pai bloqueia a espera da criança e enquanto isso a criança procura o final da entrada padrão, menos sete, então fecha a pipe(2) para o pai. Isso desbloqueia o pai, que lê o descritor compartilhado de onde o filho moveu o ponteiro do arquivo compartilhado para.

$ make sharedseek
cc     sharedseek.c   -o sharedseek
$ echo asdfasdfasdf123456 > x
$ ./sharedseek < x
read '123456
'
$ 

Isso não funcionará se a entrada padrão não for procurada. Também o pipe (ou alguma forma de comunicação) é realmente necessário, caso contrário, o pai pode correr antes do filho.

Se o descritor de arquivo não fosse compartilhado, o pai não iria ler de onde o filho moveu o ponteiro para.

    
por 04.03.2018 / 16:29

Tags