2010-08-02 25 views
11

Tôi đang đẻ trứng một quá trình từ Win32 sử dụng CreateProcess, thiết lập hStdOutputhStdError thuộc tính của STARTUPINFO để ống handle tạo ra với CreatePipe. Tôi đã có hai chủ đề đọc các đường ống, chờ đợi cho dữ liệu để trở thành có sẵn (hoặc quá trình để hoàn thành, tại thời điểm đó nó kiểm tra rằng không có dữ liệu còn lại trước khi chấm dứt thread).
Khi dữ liệu có sẵn, tôi viết đầu ra cho một hộp văn bản lớn hiệu quả.Disable đệm trên chuyển hướng ống stdout (Win32 API, C++)

Điều gì đang xảy ra là đầu ra đang được lưu vào bộ đệm, do đó quá trình chạy chậm chỉ nhận được khối dữ liệu được ném vào hộp văn bản, nhưng không phải là "khi nó xảy ra".

Tôi không chắc liệu đó có phải là đường ống đang thực hiện việc lưu vào bộ đệm hay liên quan đến chuyển hướng.

Có cách nào để đặt đường ống thành không bị chặn hoặc bắt đầu quá trình theo cách sao cho giá trị truyền dữ liệu được gửi càng sớm càng tốt?

Tôi đang thử nghiệm với một ứng dụng thử nghiệm đó in dòng thứ hai ngoài

Here is line one 
(waits one second) 
Here is line two 
(waits one second) 
... etc 
+0

Phát trực tuyến có thuận lợi khi quá trình này được ghi vào bảng điều khiển không? Trên Linux, đây là một vấn đề khá nổi tiếng, và giải pháp là phân bổ một pseudo-tty bởi vì một số chương trình kích hoạt đệm khi đầu ra không phải là một tty. Trên Windows nó không phải là phổ biến để kiểm tra các loại filetype của stdout, vì vậy tôi sẽ không mong đợi đệm khác nhau đi vào một ống vs với một giao diện điều khiển. –

+0

Có, khi nó ở trên bàn điều khiển (ví dụ: cmd.exe), nó phát như mong đợi, với sự chậm trễ và vân vân. –

+0

Quy trình ghi vào đầu ra tiêu chuẩn như thế nào? Tôi nghĩ bạn có thể đang bật chế độ đệm trong dòng C hoặc C++. – wilx

Trả lời

4

Các đệm có lẽ trong thời gian chạy C (printf vv) và không có nhiều bạn có thể làm gì về nó (IIRC nó một isatty() kiểm tra để xác định một chiến lược đệm)

+0

Đó sẽ là câu trả lời trong POSIX. Nhưng Windows không có khái niệm về một hàm tty, cũng như bất kỳ hàm 'isatty' nào. –

+1

@Ben Voigt: MS c runtime vẫn có nó: http://msdn.microsoft.com/en-us/library/f4s0ddew%28v=VS.80%29.aspx – Anders

+0

lắc đầu trong sự ngạc nhiên tại" NET khung tương đương" danh sách, không ai trong số đó là tương đương trong bất kỳ cách nào –

0

SetNamedPipeHandleState, nhưng nó chỉ kiểm soát đệm cho ống từ xa, không phải khi cả hai đầu là trên cùng một máy tính.

+0

Vâng, tôi đã nhìn thấy điều đó, nhưng, như bạn nói, nó không thay đổi bất cứ điều gì khi cả hai đầu là trên cùng một máy tính –

0

Dường như với tôi bạn có thể giải quyết vấn đề nếu bạn đặt hStdOutputhStdError của STARTUPINFOkhông để ống handle tạo ra với CreatePipe, nhưng thay vì đó bạn tạo một đường ống đặt tên (với CallNamedPipe chức năng giống hệt như bạn sử dụng nếu trước cũng sử dụng SECURITY_ATTRIBUTES với bInheritHandle = TRUE, xem http://msdn.microsoft.com/en-us/library/aa365782.aspx) và sau đó mở tại đó theo tên theo số CreateFile sử dụng cờ FILE_FLAG_WRITE_THROUGH. Giống như bạn có thể đọc trên MSDN (http://msdn.microsoft.com/en-us/library/aa365592.aspx):

Các khách hàng có thể sử dụng ống CreateFile để kích hoạt chế độ chồng chéo bằng cách xác định FILE_FLAG_OVERLAPPED hoặc để cho phép ghi qua chế độ bằng cách xác định FILE_FLAG_WRITE_THROUGH.

Vì vậy, chỉ mở lại đường ống đối với CreateFile sử dụng FILE_FLAG_WRITE_THROUGH cờ với và thiết lập xử lý/xử lý để hStdOutputhStdError của STARTUPINFO.

+1

FILE_FLAG_WRITE_THROUGH 0x80000000 chế độ Write-through được kích hoạt. Chế độ này chỉ ảnh hưởng đến các thao tác ghi trên các đường ống kiểu byte và, sau đó, ** chỉ khi các quy trình máy khách và máy chủ trên các máy tính khác nhau. ** Nếu chế độ này được kích hoạt, các chức năng ghi vào một đường ống được đặt tên không trả lại cho đến khi dữ liệu được ghi được truyền qua mạng và nằm trong bộ đệm của đường ống trên máy tính từ xa. Nếu chế độ này không được kích hoạt, hệ thống sẽ nâng cao hiệu quả hoạt động của mạng bằng cách lưu trữ dữ liệu cho đến khi số byte tối thiểu tích lũy hoặc cho đến khi thời gian tối đa trôi qua. –

Các vấn đề liên quan