Bối cảnh quan trọng ở đây là stdout
bắt buộc phải được đệm theo tiêu chuẩn như thiết lập mặc định.
Điều này gây ra một \n
để tuôn ra đầu ra.
Vì ví dụ thứ hai không chứa dòng mới, đầu ra không bị xóa và khi fork()
sao chép toàn bộ quá trình, nó cũng sao chép trạng thái của stdout
bộ đệm.
Bây giờ, các fork()
cuộc gọi này trong ví dụ của bạn tạo tổng cộng 8 quy trình - tất cả chúng đều có một bản sao trạng thái của stdout
bộ đệm.
Theo định nghĩa, tất cả các quy trình này gọi exit()
khi trở về main()
và exit()
các cuộc gọi fflush()
theo sau fclose()
trên tất cả các luồng stdio hoạt động . Điều này bao gồm stdout
và kết quả là, bạn thấy cùng một nội dung tám lần.
Đó là một cách thực hành tốt để gọi fflush()
tất cả các luồng có đầu ra đang chờ xử lý trước khi gọi fork()
hoặc để cho đứa trẻ rẽ nhánh gọi một cách rõ ràng _exit()
rằng chỉ thoát khỏi quy trình mà không xóa các luồng stdio.
Lưu ý rằng việc gọi exec()
không xóa bộ đệm stdio, vì vậy không cần quan tâm đến bộ đệm stdio nếu bạn (sau khi gọi fork()
) gọi exec()
và (nếu không) gọi _exit()
.
BTW: Để hiểu rằng bộ đệm sai có thể gây ra, đây là một lỗi cũ trong Linux đã được sửa gần đây:
Tiêu chuẩn này đòi hỏi stderr
phải được giải mã theo mặc định, nhưng Linux đã bỏ qua điều này và tạo ra stderr
dòng đệm và (thậm chí tệ hơn) được đệm hoàn toàn trong trường hợp stderr được chuyển hướng qua một đường ống. Vì vậy, các chương trình được viết cho UNIX đã thực hiện công cụ đầu ra mà không có dòng mới quá muộn trên Linux.
Xem bình luận dưới đây, nó dường như được sửa chữa ngay bây giờ.
Đây là những gì tôi làm để giải quyết vấn đề Linux này:
/*
* Linux comes with a broken libc that makes "stderr" buffered even
* though POSIX requires "stderr" to be never "fully buffered".
* As a result, we would get garbled output once our fork()d child
* calls exit(). We work around the Linux bug by calling fflush()
* before fork()ing.
*/
fflush(stderr);
Mã này không gây hại cho các nền tảng khác vì việc gọi fflush()
một luồng vừa bị xóa là không có.
./prog1 > prog1.out
) hoặc ống (./prog1 | cat
). Chuẩn bị để có tâm trí của bạn thổi. :-)