Trang man thường là tài liệu tham khảo ngắn gọn. Wikipedia là một nơi tốt hơn để chuyển sang giải thích khái niệm.
Fork nhân đôi một quy trình: nó tạo ra một quy trình con gần giống với quy trình cha (sự khác biệt rõ ràng nhất là quy trình mới có ID quy trình khác nhau). Cụ thể, fork (về mặt khái niệm) phải sao chép tất cả bộ nhớ của tiến trình cha.
Vì điều này khá tốn kém, vfork đã được phát minh để xử lý một trường hợp đặc biệt phổ biến trong đó bản sao là không cần thiết. Thông thường, điều đầu tiên mà tiến trình con thực hiện là tải một hình ảnh chương trình mới, vì vậy đây là điều xảy ra:
if (fork()) {
# parent process …
} else {
# child process (with a new copy of the process memory)
execve("/bin/sh", …); # discard the process memory
}
Cuộc execve
gọi tải một chương trình thực thi mới và điều này thay thế mã và bộ nhớ dữ liệu của quy trình bằng mã của tệp thực thi mới và bộ nhớ dữ liệu mới. Vì vậy, toàn bộ bản sao bộ nhớ được tạo bởi fork
tất cả là không có gì.
Do đó, vfork
cuộc gọi đã được phát minh. Nó không tạo ra một bản sao của bộ nhớ. Do đó vfork
rất rẻ, nhưng thật khó để sử dụng vì bạn phải đảm bảo rằng bạn không truy cập vào bất kỳ ngăn xếp hoặc không gian đống nào của quy trình trong quy trình con. Lưu ý rằng ngay cả việc đọc có thể là một vấn đề, bởi vì quá trình cha tiếp tục thực thi. Ví dụ: mã này bị hỏng (nó có thể hoạt động hoặc không hoạt động tùy thuộc vào việc đứa trẻ hoặc cha mẹ có được một lát thời gian trước hay không):
if (vfork()) {
# parent process
cmd = NULL; # modify the only copy of cmd
} else {
# child process
execve("/bin/sh", "sh", "-c", cmd, (char*)NULL); # read the only copy of cmd
}
Kể từ khi phát minh ra vfork, tối ưu hóa tốt hơn đã được phát minh. Hầu hết các hệ thống hiện đại, bao gồm cả Linux, sử dụng một hình thức sao chép khi ghi , trong đó các trang trong bộ nhớ quy trình không được sao chép tại thời điểm fork
cuộc gọi, nhưng sau đó khi cha mẹ hoặc con lần đầu tiên ghi vào trang. Nghĩa là, mỗi trang bắt đầu như được chia sẻ và vẫn được chia sẻ cho đến khi quá trình ghi vào trang đó; quá trình viết sẽ nhận được một trang vật lý mới (có cùng địa chỉ ảo). Copy-on-write làm cho vfork hầu như vô dụng, vì fork
sẽ không tạo ra bất kỳ bản sao nào trong trường hợp vfork
có thể sử dụng được.
Linux giữ lại vfork. Cuộc fork
gọi hệ thống vẫn phải tạo một bản sao của bảng bộ nhớ ảo của quy trình, ngay cả khi nó không sao chép bộ nhớ thực; vfork
thậm chí không cần phải làm điều này. Sự cải thiện hiệu suất là không đáng kể trong hầu hết các ứng dụng.