2011-12-03 22 views
10

Tôi đang đọc khoảng forkexec để làm bài kiểm tra và sách của tôi cho biết bất cứ khi nào cần chạy một quy trình mới (khác) trong hệ thống Unix, bạn sẽ chia rẽ quy trình hiện tại theo sau là execve.Trình tự thực hiện unix fork thực sự đắt tiền như âm thanh?

Tuy nhiên, nó cũng nói rằng bất cứ khi nào fork được gọi, toàn bộ hình ảnh bộ nhớ của phụ huynh được sao chép vào quy trình mới.

Sau đó, câu hỏi của tôi là: Nếu bạn có một quy trình có hình ảnh bộ nhớ thực sự lớn và bạn chỉ muốn chạy một quy trình mới? Nó không phải là một sự lãng phí các nguồn lực để sao chép tất cả các dữ liệu từ quá trình cha mẹ nếu bạn chỉ là sẽ thay thế nó ngay lập tức?

+0

+1 câu hỏi hay, cảm ơn bạn. Thường tự hỏi làm thế nào các câu trả lời nhận được phần thưởng nhiều hơn câu hỏi. Nếu không có câu hỏi thì không có câu trả lời. Và câu hỏi cũng nằm trong đầu của tôi :) – humanityANDpeace

Trả lời

5

Thông thường ngã ba không thực sự sao chép tất cả bộ nhớ, nhưng sử dụng "bản sao ghi" có nghĩa là miễn là bộ nhớ không được sửa đổi thì các trang giống nhau được sử dụng. Tuy nhiên, để tránh không có đủ bộ nhớ sau này (nên quá trình ghi vào bộ nhớ) đủ bộ nhớ phải được cấp phát.

Điều này có nghĩa là tắt từ quá trình lớn trên các hệ thống không cho phép bộ nhớ quá mức bộ nhớ phải có sẵn. Vì vậy, nếu bạn có một quá trình xử lý 8 GB, sau đó trong ít nhất một khoảng thời gian ngắn 16 GB phải có sẵn.

Xem thêm vfork và posix_spawn để biết các giải pháp khác.

+1

Câu trả lời này không may là sai - overcommitting không phải là một phần của unix, mà là một phần mở rộng của một số hệ thống.Những cái phổ biến nhất (ví dụ Linux) không theo mặc định yêu cầu 16GB đầy đủ để có sẵn trên ngã ba. –

+1

Ngay cả khi hạt nhân hệ điều hành muốn kiểm tra xem có đủ bộ nhớ không có nghĩa là nó cần có 8 GB đầy đủ vì nhiều trang đó có thể được chia sẻ nhờ các trang chỉ đọc và đọc/thực thi. – nategoose

1

Không sao chép bộ nhớ, trừ khi một trong quá trình sửa đổi bộ nhớ, trong trường hợp trang sẽ được sao chép, và nếu bạn đang gọi exec() trong tiến trình con ngay sau ngã ba() được gọi, không sao chép thực hiện.

Thực ra tôi nghĩ chắc chắn rằng exec() luôn được gọi trước khi tiến trình cha ghi vào bộ nhớ, tiến trình con luôn chạy trước.

Tôi nghĩ bạn có thể tìm thấy điều này trong Lập trình nâng cao trong UNIX

+0

Bạn nghĩ sai, phụ huynh có thể tiếp tục trước đứa trẻ, cả về lý thuyết và thực hành. Ngoài ra, quan trọng hơn, một bản sao bộ nhớ vẫn được thực hiện. –

2

Một số hệ thống đó là một trong hai rất cũ (đầu unix), hoặc rất đặc biệt (MMU-less linux) hoặc verfy crappy (cửa sổ thông qua Cygwin) cần phải tạo một bản sao đầy đủ của tất cả các trang ("mỗi byte") trên ngã ba, vì vậy tiềm năng ở đó.

Nhân unix hiện đại không sao chép tất cả bộ nhớ quá trình, thay vì chọn tạo bản sao ảo. Trong khi điều này chỉ liên quan đến một phần nhỏ của việc sao chép (các bảng trang cần phải được sao chép), điều này vẫn có thể là nhiều megabyte và mất nhiều thời gian đáng kể.

Vì vậy, câu trả lời là, có nói chung, nhưng triển khai hiện đại nhất sử dụng phần cứng để tạo bản sao ảo nhanh, nhưng ngay cả bản sao ảo đó cũng không miễn phí.

Cả hai hệ thống cũ và một số hệ thống hiện đại thực hiện lệnh gọi vfork() có giới hạn nghiêm ngặt (mặc dù ít nghiêm ngặt hơn yêu cầu POSIX cho vfork) nhưng tránh bản sao này vì lý do hiệu suất.

Để cung cấp một số số thực, trên hệ thống GNU/Linux của tôi, tôi có thể rẽ + thoát 1340 lần mỗi giây từ quy trình 20MB, nhưng chỉ 235 lần/s trên quy trình 2000MB. Trong cả hai trường hợp, vfork + execve nhanh hơn, điều này hơi khó hiểu, bởi vì nhiều người nghĩ rằng "fork is fast" và "execve phải chậm".

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