Đặt dung lượng đường ống trong Linux


7

Có cách nào để thiết lập dung lượng đường ống của các đường ống được xác định trong tập lệnh Bash (hoặc shell khác) không? Lấy ví dụ

cmd1 | cmd2

Trong các Linux gần đây, dung lượng đường ống được đặt thành 64KB theo mặc định. Tôi biết tôi có thể kiểm soát lượng dữ liệu "được đệm" giữa hai quy trình theo hai cách:

  1. Sử dụng buffer(1): vdcmd1 | buffer | cmd2
  2. Sử dụng fcntl(2)với F_SETPIPE_SZcờ từ bên trong cmd1hoặccmd2

Mỗi giải pháp đều có nhược điểm: bufferchỉ có thể được sử dụng để tăng bộ đệm; cũng ghi trên dung lượng đường ống mặc định vẫn sẽ yêu cầu đánh thức lệnh hạ lưu. fcntl, theo như tôi biết, chỉ có thể được gọi từ bên trong cmd1hoặc cmd2.

Câu hỏi của tôi là: có cách nào, khi vỏ tạo ra đường ống, để xác định trong vỏ bao nhiêu công suất ống phải có?



@ StéphaneChazelas cảm ơn vì con trỏ bây giờ tôi đã thích nghi với cách tiếp cận của bạn và DepressionDaniel. Nếu không có ai khác đi cùng với một câu trả lời tốt hơn, tôi sẽ chỉ đăng đoạn trích của mình.
CAFxX

Câu trả lời:


4

ghi trên dung lượng đường ống mặc định vẫn sẽ yêu cầu đánh thức lệnh hạ lưu

Nếu mục tiêu của bạn không phải là đánh thức lệnh hạ lưu quá thường xuyên, bạn đã thử sử dụng -ptùy chọn này bufferchưa? Nó sẽ gây ra bufferviệc giữ ghi cho đến khi bộ đệm được lấp đầy đến một tỷ lệ nhất định. Bạn có thể cần -stùy chọn để viết các đoạn lớn.

Cập nhật: D'oh, các đường ống giữa các lệnh vẫn giới hạn mọi thứ. Có thể thử sử dụng chương trình bộ điều hợp sau:

#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);
}

như trong:

adapter 1 (BIGSIZE) cmd1 | cmd2

hoặc thậm chí:

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

nếu cmd1vẫn viết nhỏ.


Ý tôi là bởi hạ lưu buffer. cmd1không thể viết nhiều hơn 64KB (dung lượng đường ống) trước khi buffercần thức dậy. Và điều đó rõ ràng áp dụng giữa buffercmd2là tốt, vì công suất đường ống luôn là 64KB.
CAFxX

@CAFxX Oh tôi thấy quan điểm của bạn bây giờ. Đang cập nhật.
DepressionDaniel

1

Dựa trên những gợi ý của DepressionDaniel và Stéphane Chazelas, tôi đã giải quyết được điều gần gũi nhất với một oneliner mà tôi có thể tìm thấy:

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

Điều này cho phép làm:

hugepipe <command> | <command>

và đường ống giữa hai lệnh sẽ có dung lượng được chỉ định thông qua fcntltập lệnh perl.

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.