Bir boru hattında sınırsız miktarda veri arabelleğe almak için yarar?


14

Okuma ve yazma hızlarını ayırmak için bir boru hattına yapıştırabileceğim bir yardımcı program var mı?

$ producer | buf | consumer

Temel olarak, bufgirdisini olabildiğince hızlı okuyan, hafızada saklayan bir yardımcı program istiyorum , böylece mümkün olduğunca hızlı consumerçalışırken tatlı zamanını alabilir producer.


Ben de böyle görmek istiyorum
Antti Haapala

stdbufAraç gibi görünmektedir sizeparametresi. Yine de çalışıp çalışmadığından emin değilim.
CMCDragonkai

Yanıtlar:


14

pv(Boru görüntüleyici) yarar bu (ile yapabilirsiniz -Bilerleme raporları veren de dahil olmak üzere, çok daha fazla seçenek) ve.


Sınırsız miktarda veri ile bunu yapmanın bir yolu var mı? Söyleyebileceğim en iyi şey, -B ile bir sayı vermem gerekiyor ve eğer üretici tüketicinin çok ötesine geçerse, üretici tekrar yavaşlayacaktır. Birden fazla tüketicinin ( producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2) bulunduğu bir durumdaysanız , bu tekrar yavaşlamaya neden olabilir.
Daniel H

pvYüzlerce kez kullandım ve bunu hiç bilmiyordum. Çok harika, teşekkürler!
Rucent88

pv -B 4096 -c -N in /dev/zero | pv -q -B 1000000000 | pv -B 4096 -c -N out -L 100k > /dev/null- Her iki pvucun da pürüzsüz olmasını bekliyorum (biri 1GB önde olsa da). mbuffer
Vi'dan

9

şunları kullanabilirsiniz dd:

producer | dd obs=64K | consumer

Her unix'te kullanılabilir.


pvBüyük olasılıkla kullanımı daha iyi olsa da , standart yardımcı programı kullanmak için +1 (ilerleme gösterir).
Mart'ta Totor

2
Bu gerçekten okuma ve yazma hızını mı bozar? Her ddseferinde sadece bir blok saklıyor gibi görünüyor , bu yüzden her şeyi blok boyutunu üretmek için gereken süre kadar geciktiriyor; Yanılıyorsam lütfen beni düzeltin. Ayrıca, bu arabelleğe alma sınırsız boyuta genişletilebilir mi, yoksa yalnızca blok boyutu için girilmişse?
Daniel H

@DanielH - şimdi.
mikeserv

7

Mbuffer'a bir göz atın . Belleğe veya bellek eşlemeli dosyaya ( -t/ -T) arabelleğe alabilir .


Diğerlerinden istediğim gibi, gerektiği kadar arabelleğe almasını söylemenin bir yolu var mı, yoksa maksimum boyutu var mı? Bu programların çoğunun maksimum boyutlara sahip olmasının ve örneğin daha küçük arabelleklerin (veya rasgele boyuttaki herhangi bir sıra uygulamasının) bağlantılı bir listesini kullanmamalarının kavramsal bir nedeni var mı?
Daniel H

Muhtemelen yetersiz bellek hatalarını önlemek. İsterseniz çok büyük bir arabellek (4 GB veya daha fazla) ayarlamak için muhtemelen bir seçenek kullanabilirsiniz (deneyin).
David Balažic

1

Bu temelde olumsuz bir cevaptır. Özellikle üretici tarafından üretilen veri oranı çok değişebiliyorsa dd, ne olduğu mbuffer, ne de pvişe yaradığı görülmektedir. Aşağıda bazı test senaryoları veriyorum. Komutu yazdıktan sonra, yaklaşık 10 saniye bekleyin, sonra yazın >(verinin sonuna gitmek, yani girişin bitmesini bekleyin).

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | dd bs=64K | less

Burada, yazdıktan sonra >, 5 saniye beklemek zorunda, yani üreticinin (zsh script) önce bloke olduğu anlamına gelir sleep 5. Artan bs32MB tampon yeterince büyük olsa mesela 32M boyutu, davranışı değiştirmez. Bunun ddgirişle devam etmek yerine çıkıştaki bloklardan kaynaklandığından şüpheleniyorum . oflag=nonblockVerileri attığı için kullanmak bir çözüm değildir.

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | mbuffer -q | less

İle mbuffer, sorun ilk satırı (foo0) hemen görünmez olmasıdır. Girişte satır arabelleğe almayı etkinleştirmek için herhangi bir seçenek yok gibi görünüyor.

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | pv -q -B 32m | less

İle pv, davranış benzer dd. Daha da kötüsü, bazen terminalden lessgirdi alamadığı için terminalde yanlış şeyler yaptığından şüpheleniyorum ; örneğin, biriyle çıkamazsınız q.


0

Standart olmayan hareket: soket arabellekleri kullanarak.

Misal:

# echo 2000000000 > /proc/sys/net/core/wmem_max
$ socat -u system:'pv -c -N i /dev/zero',sndbuf=1000000000 - | pv -L 100k -c -N o > /dev/null
        i:  468MB 0:00:16 [ 129kB/s] [  <=>                        ]
        o: 1.56MB 0:00:16 [ 101kB/s] [       <=>                   ]

Bunun için iki ek araç daha uygulandı : buffered_pipeline ve mapopentounixsocket

$ ./buffered_pipeline ! pv -i 10 -c -N 1 /dev/zero ! $((20*1000*1000)) ! pv -i 10 -L 100k -c -N 2 ! > /dev/zero
        1: 13.4MB 0:00:40 [ 103kB/s] [         <=>      ]
        2: 3.91MB 0:00:40 [ 100kB/s] [         <=>      ]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.