O socket de domínio FIFO, pipe & Unix é a mesma coisa no kernel do Linux?

26

Ouvi dizer que as FIFOs são chamadas de pipes. E eles têm exatamente a mesma semântica. Por outro lado, acho que o socket de domínio Unix é bastante semelhante ao pipe (embora eu nunca tenha feito uso dele). Então, eu me pergunto se todos eles se referem à mesma implementação no kernel do Linux. Alguma idéia?

    
por Justin 15.05.2013 / 12:55

5 respostas

33

Soquetes de domínio UNIX e FIFO podem compartilhar parte de sua implementação, mas são conceitualmente muito diferentes. O FIFO funciona em um nível muito baixo. Um processo grava bytes no pipe e outro lê a partir dele. Um soquete de domínio UNIX tem o mesmo comportamento de um soquete TCP / IP.

Um soquete é bidirecional e pode ser usado por muitos processos simultaneamente. Um processo pode aceitar muitas conexões no mesmo soquete e atender vários clientes simultaneamente. O kernel fornece um novo descritor de arquivo sempre que connect(2) ou accept(2) é chamado no soquete. Os pacotes sempre vão para o processo certo.
Em um FIFO, isso seria impossível. Para comunicação bidirecional, você precisa de dois FIFOs e precisa de um par de FIFOs para cada um de seus clientes. Não há como escrever ou ler de maneira seletiva, porque são formas muito mais primitivas de se comunicar.

Tubulações anônimas e FIFOs são muito semelhantes. A diferença é que os pipes anônimos não existem como arquivos no sistema de arquivos, então nenhum processo pode open(2) it. Eles são usados por processos que os compartilham por outro método. Se um processo abrir um FIFO e executar, por exemplo, um fork(2) , seu filho herdará seus descritores de arquivo e, entre eles, o canal.

Os soquetes de domínio, os pipes anônimos e os FIFOs do UNIX são semelhantes no fato de usar segmentos de memória compartilhada. Os detalhes da implementação podem variar de um sistema para outro, mas a idéia é sempre a mesma: anexa a mesma parte da memória em dois mapeamentos de memória de processos distintos para que eles compartilhem dados
( edite: isso seria uma maneira óbvia de implementá-lo, mas não é como realmente é feito no Linux, que simplesmente usa a memória do kernel para os buffers, veja a resposta de @ tjb63 abaixo).
O kernel então manipula as chamadas do sistema e abstrai o mecanismo.

    
por 15.05.2013 / 14:35
6

Existe uma boa discussão sobre isso aqui: link

Até onde eu posso ver, os slides da apresentação e a fonte @ link - os fifo's são implementados como um empacotador em volta do pipe, e os próprios pipe's são implementados através do sistema de arquivos virtual do pipefs.

@lgeorget - Os canais parecem usar memória kernel para buffers entre os leitores e gravadores - eles não usam 'memória compartilhada' como tal e copiam memória entre espaços de endereço de usuário e de kernel (por exemplo, pipe_read chamadas pipe_iov_copy_to_user , que chama __copy_to_user_inatomic (ou copy_to_user ). __copy_to_user_inatomic chamadas copy_user_generic , que está em várias implementações do ASM.

    
por 21.07.2013 / 04:09
2

Um "FIFO" e um " named pipe" é a mesma coisa - embora seja bem diferente de como um shell manipula um "pipe" (|) entre dois comandos na linha de comando.

Um pipe nomeado (FIFO) é um único "arquivo" compartilhado por dois programas, onde um grava nele e o outro lê a partir dele ... Um soquete, por outro lado, é uma "conexão" entre dois "arquivos" - que pode usar uma rede e estar em computadores separados - onde um programa lê / escreve em um "arquivo" e outro programa lê / escreve no outro ... Eu não acho que eles sejam similares ... Por outro lado, tanto sockets como pipes nomeados - assim como arquivos, dispositivos, links simbólicos - todos usam inodes, e todos eles implementam algumas características comuns (como ler e escrever).

    
por 15.05.2013 / 14:18
0

Eu não penso assim Justin. Se não estou enganado, e possivelmente sou, acho que os FIFOs usam um arquivo no disco, e os soquetes do Unix Domain usam a memória do kernel.

Além disso, como acréscimo ao pôster acima, que mencionou que os soquetes de domínio Unix são bidirecionais, isso ocorre apenas quando se usa um soquete SOCK_STREAM. SOCK_DGRAM Os soquetes de domínio Unix são, na verdade, unidirecionais e só podem enviar () do código chamado connect (), para o código que chamou bind ().

Naturalmente, o código que chama connect () também deve chamar bind () para criar seu próprio endpoint, mas isso não tem nada a ver com sua pergunta.

    
por 02.07.2013 / 22:20
0

Meus 2 centavos ... FIFO e UNIX são ambos bidirecionais (semelhantes) mas o socket tem uma topologia em estrela enquanto um FIFO é apenas uma fila (e portanto não pode substituir um ao outro), sim sua implementação pode compartilhar código internamente .

**

char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDWR);   //so that you can read/write to it
 ...
write(fd, buff1, sizeof(buff1));  
getchar();//wait till some one reds this and writes something else
int sz=read(fd, buff1, sizeof(buff1));  //read that something**
    
por 09.10.2018 / 07:36