Khi nào nên gọi fork () và exec ()?


9

Tôi đang tìm hiểu về các lệnh fork () và exec (). Có vẻ như fork () và exec () thường được gọi cùng nhau. (fork () tạo một quy trình con mới và exec () thay thế hình ảnh quy trình hiện tại bằng một quy trình mới.) Tuy nhiên, trong trường hợp nào bạn có thể tự gọi mỗi chức năng? Có những kịch bản như thế này?


2
Forkbomb truyền thống: while (1) fork (); để hog tài nguyên hệ thống.
Joshua

Câu trả lời:


22

Chắc chắn rồi! Một mô hình phổ biến trong các chương trình "trình bao bọc" là thực hiện nhiều việc khác nhau và sau đó tự thay thế bằng một số chương trình khác chỉ bằng một execcuộc gọi (không có ngã ba)

#!/bin/sh
export BLAH_API_KEY=blub
...
exec /the/thus/wrapped/program "$@"

Một ví dụ thực tế về điều này là GIT_SSH(mặc dù git(1)cũng cung cấp GIT_SSH_COMMANDnếu bạn không muốn thực hiện phương pháp chương trình trình bao bọc ở trên).

Chỉ dùng ngã ba được sử dụng khi sinh ra một loạt các quy trình công nhân điển hình (ví dụ: Apache httpdở chế độ ngã ba (mặc dù chỉ phù hợp với các quy trình cần đốt cháy CPU chứ không phải các quy trình xoay vòng ngón tay cái của chúng chờ I / O mạng xảy ra) ) hoặc để phân tách đặc quyền được sử dụng bởi sshdvà các chương trình khác trên OpenBSD (không thực hiện)

$ doas pkg_add pstree
...
$ pstree | grep sshd
 |-+= 70995 root /usr/sbin/sshd
 | \-+= 28571 root sshd: jhqdoe [priv] (sshd)
 |   \-+- 14625 jhqdoe sshd: jhqdoe@ttyp6 (sshd)

Các rootsshd đã trên máy khách kết nối chia hai ra một bản sao của chính nó (28.571) và sau đó một bản sao (14.625) cho privilege separation.


14

Có nhiều.

Các chương trình gọi fork()mà không exec()có thường theo mô hình của các quy trình nhân viên trẻ em sinh sản để thực hiện các nhiệm vụ khác nhau trong các quy trình riêng biệt đến quy trình chính. Bạn sẽ tìm thấy điều này trong các chương trình khác nhau như dhclient, php-fpm, và urxvtd.

Một chương trình mà các cuộc gọi exec()mà không fork()chuỗi tải , bao phủ quá trình của nó với một hình ảnh chương trình khác nhau. Có cả một nhóm văn hóa của các tiện ích tải chuỗi thực hiện những việc cụ thể để xử lý trạng thái và sau đó thực thi một chương trình khác để chạy với trạng thái quy trình được sửa đổi đó. Những tiện ích như vậy là phổ biến trong bộ công cụ dịch vụ và quản lý hệ thống của daemontools , nhưng không giới hạn ở những tiện ích này. Một vài ví dụ:

Các bộ công cụ gia đình daemontools có rất nhiều công cụ như vậy, từ machineenvthông qua find-matching-jvmđến runtool.


2

Ngoài các câu trả lời khác, trình gỡ lỗi, sử dụng ptrace, thường sử dụng khoảng cách giữa forkexec. Một PTRACE_TRACEMEtrình gỡ lỗi nên đánh dấu chính nó để chỉ ra rằng nó đang được theo dõi bởi quá trình mẹ của nó - trình gỡ lỗi. Điều này là để cung cấp các quyền cần thiết cho trình gỡ lỗi.

Vì vậy, một trình sửa lỗi đầu tiên sẽ ngã ba chính nó. Đứa trẻ sẽ gọi ptracevới PTRACE_TRACEMEvà sau đó gọi exec. Bất cứ chương trình nào mà đứa trẻ thực hiện bây giờ sẽ được phụ huynh truy nguyên.


Có nhiều ví dụ về việc thực hiện giữa fork và exec, phổ biến nhất là chuyển hướng I / O (ví dụ: thiết lập đường ống). Nhưng câu hỏi là về làm ngã ba mà không có người thực hiện nào cả.
Barmar

0

thực hiện mà không cần ngã ba

Có ít nhất hai lý do tại sao bạn muốn làm một việc như vậy:

  1. Chuỗi tải. Hình ảnh quá trình hiện tại được thay thế bằng một cái gì đó khác nhau.
  2. Khởi động lại chương trình hiện đang chạy (ví dụ có thể xảy ra khi bạn SIGHUP hoặc quá trình máy chủ như vậy, tải lại mọi thứ và thực hiện một khởi đầu hoàn toàn mới). Theo một cách nào đó, người ta có thể lập luận rằng đây là tải chuỗi, chỉ trùng hợp với cùng một chương trình.

ngã ba mà không thực hiện

Đó là điều mà mọi daemon làm mỗi khi nó bắt đầu (thực tế là hai lần). Điều này thực hiện một số điều, trong số đó, vỏ không bị treo (vì quá trình ban đầu mà vỏ chờ kết thúc) và daemon không còn được điều khiển bởi thiết bị đầu cuối, vì vậy việc đóng cửa sổ vỏ sẽ không giết daemon.

Một cách sử dụng phổ biến khác là giả mạo trẻ em công nhân, vốn đã nổi tiếng bởi máy chủ web apache khoảng 25 năm trước (ngày nay điều này không còn được coi là tình trạng của nghệ thuật nữa do rất dễ xảy ra sự cố sấm sét, nhưng nó chắc chắn cung cấp máy chủ đơn giản nhất, mạnh mẽ nhất có thể).

Tuy nhiên, một cách sử dụng phổ biến khác là tạo một ảnh chụp nhanh nhất quán. forkkhông chỉ tạo ra một quy trình, nó còn sao chép (trên lý thuyết, trong thực tế, nó chỉ đánh dấu các trang sao chép trên ghi) không gian địa chỉ. Điều này (về nguyên tử) tạo ra một ảnh chụp nhanh dữ liệu chương trình hoàn chỉnh mà phụ huynh không còn có thể sửa đổi.
Một số chương trình tận dụng điều đó. Ví dụ, redis lưu dữ liệu vào đĩa (ở trạng thái nhất quán) đồng thời sửa đổi tập dữ liệu đồng thời. Điều này chỉ hoạt động vì forkđã tạo một ảnh chụp nhanh nhất quán mà không thấy các sửa đổi được thực hiện bởi quy trình cha.


Ngày nay, thực tế rất ít người, với hầu hết không làm điều này như là tiêu chuẩn hoặc không có chế độ thường được sử dụng. Đó là một sai lầm khi rẽ nhánh dẫn đến sự không phù hợpkinh hoàng , và là một trong những sai lầm của sai lầm ngụy biện . Sai lầm này cuối cùng đã rơi ra khỏi sự ủng hộ.
JdeBP
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.