[Tôi sẽ lặp lại một phần câu trả lời của tôi từ đây .]
Tại sao không chỉ có một lệnh tạo ra một quy trình mới từ đầu? Không phải là vô lý và không hiệu quả để sao chép một cái mà sẽ chỉ được thay thế ngay lập tức?
Trên thực tế, điều đó có thể sẽ không hiệu quả vì một vài lý do:
"Bản sao" được tạo bởi fork()
một chút trừu tượng, vì kernel sử dụng hệ thống sao chép trên ghi ; tất cả những gì thực sự phải được tạo ra là một bản đồ bộ nhớ ảo. Nếu bản sao ngay lập tức gọi exec()
, hầu hết dữ liệu sẽ được sao chép nếu nó bị sửa đổi bởi hoạt động của quy trình thực sự không bao giờ phải sao chép / tạo vì quy trình không làm bất cứ điều gì cần sử dụng.
Các khía cạnh quan trọng khác nhau của quy trình con (ví dụ, môi trường của nó) không phải được sao chép hoặc đặt riêng lẻ dựa trên phân tích phức tạp của bối cảnh, v.v. Chúng chỉ được coi là giống như quy trình gọi và đây là hệ thống khá trực quan mà chúng ta quen thuộc.
Để giải thích thêm 1 chút nữa, bộ nhớ được "sao chép" nhưng không bao giờ được truy cập sau đó không bao giờ thực sự được sao chép, ít nhất là trong hầu hết các trường hợp. Một ngoại lệ trong ngữ cảnh này có thể là nếu bạn rẽ nhánh một quy trình, sau đó có lối thoát quy trình cha mẹ trước khi đứa trẻ tự thay thế exec()
. Tôi nói có thể bởi vì phần lớn cha mẹ có thể được lưu trong bộ nhớ cache nếu có đủ bộ nhớ trống và tôi không chắc mức độ này sẽ được khai thác ở mức độ nào (điều này phụ thuộc vào việc triển khai HĐH).
Tất nhiên, điều đó không có trên làm cho bề mặt sử dụng một bản sao hơn hiệu quả hơn là sử dụng một phiến đá trắng - ngoại trừ "những phiến đá trắng" không phải là nghĩa đen không có gì, và phải liên quan đến phân bổ. Hệ thống này có thể có một generic trống / mới quy trình mẫu mà nó sao chép cùng một cách, 1 nhưng điều đó sẽ sau đó không thực sự tiết kiệm bất cứ điều gì so với ngã ba copy-on-write. Vì vậy, # 1 chỉ chứng minh rằng sử dụng quy trình trống "mới" sẽ không hiệu quả hơn.
Điểm # 2 giải thích tại sao sử dụng ngã ba có khả năng hiệu quả hơn. Môi trường của một đứa trẻ được thừa hưởng từ cha mẹ của nó, ngay cả khi đó là một thực thi hoàn toàn khác. Ví dụ: nếu tiến trình cha là shell và trình duyệt web con $HOME
vẫn giống nhau cho cả hai, nhưng vì sau đó có thể thay đổi nó, đây phải là hai bản sao riêng biệt. Một trong những đứa trẻ được sản xuất bởi bản gốc fork()
.
1. Một chiến lược có thể không có nhiều ý nghĩa theo nghĩa đen, nhưng quan điểm của tôi là việc tạo ra một quy trình liên quan đến nhiều hơn là sao chép hình ảnh của nó vào bộ nhớ từ đĩa.