nhánh rẽ nhánh () hơn dự kiến?


Câu trả lời:


245

Người fork()nguyên thủy thường kéo dài trí tưởng tượng. Cho đến khi bạn cảm nhận được điều đó, bạn nên tìm ra trên giấy mỗi hoạt động là gì và chiếm số lượng quy trình. Đừng quên rằng fork () tạo ra một bản sao gần như hoàn hảo của quy trình hiện tại. Sự khác biệt đáng kể nhất (đối với hầu hết các mục đích) là fork()giá trị trả về khác nhau giữa cha mẹ và con cái. (Vì mã này bỏ qua giá trị trả về, nên nó không có sự khác biệt.)

Vì vậy, lúc đầu, có một quá trình. Điều đó tạo ra một quy trình thứ hai, cả hai đều in một dấu chấm và vòng lặp. Trong lần lặp thứ hai, mỗi lần tạo một bản sao khác, do đó, có bốn quy trình in một dấu chấm, rồi thoát. Vì vậy, chúng tôi có thể dễ dàng chiếm sáu chấm, như bạn mong đợi.

Tuy nhiên, những gì printf()thực sự làm là đệm đầu ra của nó. Vì vậy, dấu chấm đầu tiên từ khi chỉ có hai quá trình không xuất hiện khi được viết. Những dấu chấm đó vẫn còn trong bộ đệm Bộ đệm được nhân đôi tại fork (). Chỉ đến khi quá trình chuẩn bị thoát ra thì dấu chấm đệm mới xuất hiện. Bốn quy trình in một dấu chấm đệm, cộng với quy trình mới cho 8 chấm.

Nếu bạn muốn tránh hành vi đó, hãy gọi fflush(stdout);sau printf().


12
Cảm ơn, tôi không biết rằng bộ đệm trùng lặp với fork (). Nó giải thích một hành vi kỳ lạ như vậy.
Nikolay Kovalenko

1
Không nên cho 10 chấm chứ không phải 8? Vì 4 thế hệ con thứ hai thừa hưởng dấu chấm đệm, thêm dấu chấm của chúng, sau đó xóa khi thoát, chúng sẽ in tổng cộng 8 dấu chấm, nhưng sau đó, hai quá trình thế hệ thứ nhất vẫn sẽ có một dấu chấm mỗi lần đệm và xóa chúng khi thoát, cho tổng cộng 10.
psusi

12
@psusi Một trong những quy trình thế hệ thứ hai quy trình thế hệ thứ nhất. fork()không tạo 2 rồi thoát, nó chỉ tạo thêm 1 tiến trình.
Izkata

70

Bạn có bộ đệm không được cam kết trong các luồng đầu ra . thiết bị xuất chuẩn được đệm dòng và bộ đệm được sao chép cùng với phần còn lại của quá trình. Khi chương trình kết thúc, bộ đệm không cam kết được viết hai lần (một lần cho mỗi quy trình). Cả hai sử dụng

printf("a\n");

printf("a "); fflush(stdout);

không thể hiện vấn đề

Trong ví dụ đầu tiên của bạn, bạn tạo bốn quy trình có mỗi hai dấu chấm trong bộ đệm luồng đầu ra của chúng. Khi mỗi luồng kết thúc, nó sẽ xóa bộ đệm của nó, tạo ra tám dấu chấm.


2

khi tôi = 0

Quá trình_1: Văn bản được đệm = 1 chấm

Process_2 (được tạo bởi Process_1): Văn bản được đệm = 1 chấm

khi tôi = 1

Process_3 (được tạo bởi Process_1): Kế thừa 1 chấm được đệm từ Process_1 và tự in 1 chấm. Trong tổng số Process_3 in 2 dấu chấm.

Process_4 (được tạo bởi Process_2): Kế thừa 1 chấm được đệm từ Process_2 và tự in 1 chấm. Trong tổng số Process_4 in 2 dấu chấm.

Process_1: In 2 chấm (Một chấm được đệm khi i = 0 và một chấm khác khi i = 1)

Process_2: In 2 chấm (Một chấm được đệm khi i = 0 và một chấm khác khi i = 1)

Đầu ra cuối cùng: 8 chấm. :)

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.