Defina a capacidade de canalização no Linux

7

Existe uma maneira de definir a capacidade de pipe dos pipes definidos em um script Bash (ou outro shell)? Tome, por exemplo,

cmd1 | cmd2

Em Linuxes recentes, a capacidade de canalização é definida como 64 KB por padrão. Eu sei que posso controlar a quantidade de dados "armazenados em buffer" entre os dois processos de duas maneiras:

  1. Usando buffer(1) : por exemplo %código%
  2. Usando cmd1 | buffer | cmd2 com o sinalizador fcntl(2) de dentro de F_SETPIPE_SZ ou cmd1

Cada solução tem desvantagens: cmd2 só pode ser usado para aumentar o buffer; também grava sobre a capacidade de canal padrão ainda exigirá a ativação do comando downstream. buffer , até onde eu sei, só pode ser chamado de dentro de fcntl ou cmd1 .

Minha pergunta é: existe alguma maneira, quando o shell cria o pipe, para especificar no shell quanta capacidade o pipe deve ter?

    
por CAFxX 05.12.2016 / 21:57

2 respostas

1

Com base nas sugestões de DepressedDaniel e Stéphane Chazelas, decidi o mais próximo possível de um oneliner:

function hugepipe {
  perl -MFcntl -e 'fcntl(STDOUT, 1031, 1048576) or die $!; exec { $ARGV[0] } @ARGV or die $!' "$@"
}

Isso permite:

hugepipe <command> | <command>

e o pipe entre os dois comandos terá a capacidade especificada por meio do fcntl no script perl.

    
por 06.12.2016 / 08:55
4

writes over the default pipe capacity will still require waking up the downstream command

Se sua meta não for acordar o comando downstream com muita frequência, você tentou usar a opção -p para buffer ? Isso deve fazer com que buffer mantenha as gravações até que o buffer seja preenchido com uma determinada porcentagem. Você pode precisar da opção -s para escrever grandes blocos.

Atualização: D'oh, os canos entre os comandos ainda limitam as coisas. Talvez tente usar o seguinte programa de adaptador:

#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char** argv)
{
  fcntl(atoi(argv[1]), F_SETPIPE_SZ, atoi(argv[2]));
  execvp(argv[3],argv+3);
  while (1);
}

como em:

adapter 1 (BIGSIZE) cmd1 | cmd2

ou até mesmo:

adapter 1 (BIGSIZE) cmd1 | adapter 1 (BIGSIZE) buffer [args] | cmd2

se cmd1 ainda faz pequenas gravações.

    
por 05.12.2016 / 22:08