Tiện ích để đệm một lượng dữ liệu không giới hạn trong một đường ống?


13

Có một tiện ích mà tôi có thể dính vào một đường ống để phân tách tốc độ đọc và ghi không?

$ producer | buf | consumer

Về cơ bản, tôi muốn một tiện ích bufđọc đầu vào của nó càng nhanh càng tốt, lưu trữ nó trong bộ nhớ để consumercó thể mất thời gian ngọt ngào trong khi producerchạy càng nhanh càng tốt.


Tôi cũng muốn thấy như vậy
Antti Haapala

Các stdbufcông cụ dường như là một sizetham số. Tôi không chắc chắn nếu nó hoạt động mặc dù.
CMCDragonkai

Câu trả lời:


13

Các pv(xem ống) tiện ích có thể làm được điều này (với -Btùy chọn) và nhiều hơn nữa, bao gồm cung cấp báo cáo tiến độ.


Có cách nào để làm điều này với một lượng dữ liệu không giới hạn? Theo như tôi có thể nói, tôi cần cung cấp một số với -B và nếu nhà sản xuất vượt xa người tiêu dùng, nhà sản xuất sẽ chậm lại. Nếu bạn đang ở trong tình huống có nhiều người tiêu dùng ( producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2), điều này có thể gây ra chậm lại.
Daniel H

Tôi đã sử dụng pvhàng trăm lần và không bao giờ biết điều này. Rất tuyệt vời, Cảm ơn bạn!
Rucent88

pv -B 4096 -c -N in /dev/zero | pv -q -B 1000000000 | pv -B 4096 -c -N out -L 100k > /dev/null- Tôi hy vọng cả hai pvđầu cuối đều trơn tru (mặc dù một đầu là 1GB phía trước). Nó không hoạt động theo cách này, không giống nhưmbuffer
Vi.

9

bạn có thể sử dụng dd:

producer | dd obs=64K | consumer

Nó có sẵn trên mọi unix.


+1 để sử dụng tiện ích tiêu chuẩn, mặc dù pvcó lẽ sẽ dễ sử dụng hơn (hiển thị tiến trình).
Totor 17/03/13

2
Điều đó thực sự làm giảm tốc độ đọc và viết? Có vẻ như ddchỉ lưu trữ một khối tại một thời điểm, vì vậy nó sẽ chỉ trì hoãn mọi thứ bằng lượng thời gian cần thiết để tạo kích thước khối; Nêu tôi sai vui long chân chỉnh tôi. Ngoài ra, bộ đệm này có thể được mở rộng đến kích thước không giới hạn hay chỉ bất kỳ thứ gì được nhập cho kích thước khối?
Daniel H

@DanielH - bây giờ.
mikeerv

7

Hãy xem mbuffer . Nó có thể đệm vào bộ nhớ hoặc tập tin ánh xạ bộ nhớ ( -t/ -T).


Như tôi đã hỏi những người khác, có cách nào để bảo nó đệm nhiều nhất có thể không, hay nó có kích thước tối đa không? Có một lý do khái niệm tại sao hầu hết các chương trình này có kích thước tối đa và, ví dụ, không sử dụng danh sách liên kết của các bộ đệm nhỏ hơn (hoặc bất kỳ triển khai hàng đợi kích thước tùy ý nào khác)?
Daniel H

Có lẽ để ngăn ngừa lỗi ngoài bộ nhớ. Bạn có thể có thể sử dụng một tùy chọn để đặt bộ đệm rất lớn (4GB hoặc hơn) nếu bạn muốn (thử nó).
David Balažic

1

Đây về cơ bản là một câu trả lời tiêu cực. Dường như không phải dd, cũng không mbuffer, thậm chí không pvhoạt động là tất cả các trường hợp, đặc biệt nếu tốc độ dữ liệu do nhà sản xuất tạo ra có thể thay đổi rất nhiều. Tôi đưa ra một số thử nghiệm dưới đây. Sau khi gõ lệnh, đợi khoảng 10 giây, sau đó nhập >(để đi đến cuối dữ liệu, tức là đợi kết thúc đầu vào).

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

Ở đây, sau khi gõ >, người ta phải đợi 5 giây, nghĩa là nhà sản xuất (tập lệnh zsh) đã bị chặn trước sleep 5. Việc tăng bskích thước lên ví dụ 32M sẽ không thay đổi hành vi, mặc dù bộ đệm 32 MB đủ lớn. Tôi nghi ngờ rằng điều này là do ddcác khối trên đầu ra thay vì tiếp tục với đầu vào. Sử dụng oflag=nonblockkhông phải là một giải pháp vì điều này loại bỏ dữ liệu.

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

Với mbuffer, vấn đề là dòng đầu tiên (foo0) không xuất hiện ngay lập tức. Dường như không có bất kỳ tùy chọn nào để kích hoạt bộ đệm dòng trên đầu vào.

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

Với pv, hành vi tương tự như dd. Tồi tệ hơn, tôi nghi ngờ rằng nó làm những điều sai trái với thiết bị đầu cuối vì đôi khi lesskhông thể nhận được đầu vào từ thiết bị đầu cuối; ví dụ, người ta không thể bỏ nó với q.


0

Di chuyển không chuẩn: sử dụng bộ đệm ổ cắm.

Thí dụ:

# 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] [       <=>                   ]

Đã triển khai hai công cụ bổ sung cho việc này: buffered_pipelinemapopentounixsocket

$ ./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] [         <=>      ]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.