gato não-bloqueador / multi-threaded

3

cat está bloqueando o que eu vejo no código , isto é, usa o bloqueio read() e depois usa o bloqueio write() .

Eu quero chamar alguma ferramenta onde eu desabilito todos os buffers stdout por finalidade (por exemplo, como descrito aqui ), porque essa ferramenta pode chamar subprocessos e eu quero que todas as escritas de todos os subprocessos no stdout ocorram ao mesmo tempo em que são escritas ao mesmo tempo.

Então, quero canalizar esse stdout para uma versão multi-threaded de cat (ou mais). O objetivo é que o stdout real seja lento (é um arquivo no disco), mas não quero que a ferramenta seja interrompida quando ele tentar gravar no stdout. Se eu apenas fizesse

stdbuf -oL mytool

então ele iria travar quando o disco estivesse ocupado ou assim. Quando eu faço

stdbuf -oL mytool | cat

Na verdade, não tenho certeza do que vai acontecer. Eu poderia obter algum buffer adicional pelo buffer de canal do kernel , embora eu ache que não será usado quando eu desativar o stdout buffer de mytool . E então o stdout de cat também será armazenado em buffer por padrão, mas no momento em que cat realmente grava seu stdout, ele pode travar. mytool irá travar quando escrever algo e cat não estiver lendo ao mesmo tempo.

É por isso que estou procurando por um cat multissegmentado que lê ao mesmo tempo quando escreve, portanto, gravar no stdin de multi-threaded-cat nunca estará bloqueando (ou apenas o bloqueio suave ou o que quer que você chamaria isso). Basicamente, introduz outro buffer no espaço do usuário em multi-threaded-cat . Quando multi-threaded-cat trava ao tentar gravar no stdout, não importa, porque ele ainda lerá de stdin em paralelo. Então eu quero fazer:

stdbuf -oL mytool | multi-threaded-cat

Eu quero que multi-threaded-cat consuma os dados de entrada sempre o mais rápido possível. É por isso que acho que provavelmente deve ser multi-threaded. Caso contrário, se usar write (), isso pode bloquear ou pelo menos dar um pequeno hickup e no meio-tempo, ele não pode ler () de stdin.

Eu também quero que multi-threaded-cat anote os dados assim que possível. Por isso, não deve primeiro preencher o seu próprio buffer e, em seguida, escrever, quero que ele escreva sempre de imediato.

Meu caso de uso é o seguinte: o mytool, incluindo alguns subprocessos, grava algumas informações de registro no stdout. stdbuf é importante para que eu não tenha nenhum atraso na saída e também que todos os stdouts dos subprocessos sejam sincronizados. Todo o stdout será redirecionado para um arquivo de log em um servidor de arquivos que é um pouco lento e reduzirá muito o desempenho quando ele aguardar a conclusão de todas as gravações. Então é por isso que eu quero algo como multi-threaded-cat no meio.

Existe tal ferramenta?

Acabei de implementar minha própria ferramenta aqui . Usar isso já me dá um aumento de velocidade de 800%, comparado a não usá-lo. Mas talvez haja outras ferramentas ou outras maneiras de fazer o que eu quero?

    
por Albert 29.04.2016 / 14:04

1 resposta

3

“Multithreaded” é um detalhe de implementação e não o que você realmente precisa: uma implementação cat multissegmentada ainda pode bloquear com um thread aguardando o outro thread porque está esperando para ter um lugar para colocar os dados que são lidos. O que você está procurando é um não bloqueador cat , com um buffer potencialmente ilimitado.

O utilitário sponge de moreutils de Joey Hess é uma versão extrema disso: primeiro lê o arquivo inteiro na memória Em seguida, grava a saída. Isso pode ou não funcionar para você.

pv permite que você especifique um tamanho de buffer. Você não pode ter um buffer ilimitado, mas você pode definir um tamanho máximo muito grande (torná-lo tão grande quanto a sua memória, se quiser), o buffer só é alocado sob demanda.

stdbuf -oL mytool | pv -q -B 1g >output-file
    
por 30.04.2016 / 02:58

Tags