2011-10-15 24 views
12

Tôi không hiểu tại sao Unix có fork() để tạo quy trình mới. Trong Win32 API, chúng tôi có CreateProcess() tạo một quy trình mới và tải một tệp thực thi vào không gian địa chỉ của nó, sau đó bắt đầu thực hiện từ điểm nhập. Tuy nhiên, Unix cung cấp nĩa để tạo một quy trình mới và tôi không hiểu tại sao tôi lại sao chép quy trình của mình nếu tôi muốn chạy một tiến trình khác.Tại sao Unix có fork() nhưng không phải CreateProcess()?

Vậy cho tôi hỏi hai câu hỏi sau:

  1. Nếu fork() và sau đó exec() là hiệu quả hơn, tại sao không phải là có một chức năng forkexec(const char *newProc) vì chúng ta sẽ gọi exec() sau fork() gần như trong mọi trường hợp?
  2. Nếu nó không hiệu quả hơn, tại sao tất cả mọi người đều tồn tại?
  3. hệ điều hành

Trả lời

11

Cuộc gọi fork() là đủ. Nó cũng linh hoạt hơn, nó cho phép bạn thực hiện những điều như điều chỉnh chuyển hướng I/O trong quá trình con, thay vì làm phức tạp cuộc gọi hệ thống để tạo quy trình. Với các chương trình SUID hoặc SGID, nó cho phép đứa trẻ mất đặc quyền cao của nó trước khi thực hiện quá trình khác.

Nếu bạn muốn có một cách phức tạp để tạo quy trình, hãy tra cứu hàm posix_spawn().

#include <spawn.h> 

int posix_spawn(pid_t *restrict pid, const char *restrict path, 
     const posix_spawn_file_actions_t *file_actions, 
     const posix_spawnattr_t *restrict attrp, 
     char *const argv[restrict], char *const envp[restrict]); 

int posix_spawnp(pid_t *restrict pid, const char *restrict file, 
      const posix_spawn_file_actions_t *file_actions, 
     const posix_spawnattr_t *restrict attrp, 
     char *const argv[restrict], char *const envp[restrict]); 

Sự khác biệt là posix_spawnp() hiện một tìm kiếm trên PATH cho thực thi.

Có toàn bộ các chức năng khác để xử lý các loại posix_spawn_file_actions_tposix_spawnattr_t (theo liên kết 'Xem thêm' ở cuối trang người được tham chiếu).

Điều này khá giống với CreateProcess() trên Windows. Đối với hầu hết các phần, mặc dù, bằng cách sử dụng fork() theo sau là exec() là đơn giản hơn.


Tôi không hiểu ý bạn là gì. Mã quy trình con sẽ được viết bởi tôi, vậy sự khác nhau giữa việc viết if (fork() == 0) là gì và đặt mã này vào đầu số main() của trẻ?

Rất thường xuyên, mã bạn thực thi không phải do bạn viết, vì vậy bạn không thể sửa đổi những gì xảy ra trong quá trình bắt đầu của trẻ. Hãy nghĩ về một cái vỏ; nếu các chương trình duy nhất bạn chạy từ trình bao là những chương trình bạn đã viết, cuộc sống sẽ rất nghèo nàn.

Khá thường xuyên, mã bạn thực thi sẽ được gọi từ nhiều nơi khác nhau. Đặc biệt, hãy nghĩ về một trình bao và một chương trình đôi khi sẽ được thực hiện trong một đường ống và đôi khi được thực hiện mà không cần đường ống. Chương trình được gọi không thể cho biết các chuyển hướng I/O và các bản sửa lỗi nào cần thực hiện; chương trình gọi điện thoại biết.

Nếu chương trình gọi đang chạy với đặc quyền nâng cao (đặc quyền SUID hoặc SGID), bình thường là bạn muốn tắt các chương trình đó trước khi chạy một chương trình khác. Dựa vào chương trình khác để biết phải làm gì là ... ngu ngốc.

+0

tôi không hiểu ý bạn là gì. mã quá trình con sẽ được viết bởi tôi vì vậy sự khác biệt giữa viết là gì (fork() == 0) và đặt mã này vào đầu phần chính của con()? –

+0

hmm, do đó, bạn nói rằng nó chỉ là dễ dàng hơn với fork() - exec() cặp vợ chồng để làm những việc như vậy (i/o chuyển hướng, lấy lại đặc quyền, vv ..) tôi đã làm cho nó đúng? –

+1

Có: so với các mâu thuẫn cần thiết cho 'posix_spawn()', nó đơn giản hơn nhiều khi sử dụng 'fork()' và sau đó yêu cầu con thực hiện các hành động cần thiết, trước khi sử dụng 'exec()'. Đọc lý do cho 'posix_spawn()'; nó khá ngộ nghĩnh (hoặc, ít nhất, đó là với tôi). Danh sách những thứ bạn có thể làm với 'posix_spawn()' là ấn tượng, nhưng nó cũng phức tạp hơn những gì 'fork()' cung cấp. –

3

UNIX-like (ít nhất là mới hơn Linux và BSD kernel) thường có một rất hiệu quảfork thực hiện - đó là "giá rẻ như vậy" rằng có những "luồng" triển khai dựa trên nó trong một số ngôn ngữ .

Cuối cùng, hàm forkexec là ~ n - đối với một số giá trị nhỏ của n - dòng mã ứng dụng.

Tôi chắc chắn muốn cửa sổ có như vậy một hữu ích ForkProcess :(

Chúc mừng mã hóa.


Một cnicutar đề cập, Copy-On-Write (COW) là một chiến lược được sử dụng.

+2

ok nhưng nếu tôi sẽ làm thay đổi quá trình này thành khác sau khi ngã ba rất hiệu quả, không phải là nó tốt hơn để tạo mới quá trình ngay từ đầu? sau đó tôi không phải lặp lại quá trình của riêng tôi. đây là những gì tôi không nhận được –

+0

@Ali Veli Modern dĩa không lặp lại quá trình ở tất cả. Tra cứu "copy on write". – cnicutar

+0

cho phép nói rằng tôi sẽ tạo một quy trình mới. c-o-w hay không, ngã ba có làm gì đúng không? vì vậy tôi nghĩ rằng nếu tôi chỉ cần tạo ra một quy trình mới, tôi sẽ không làm điều này một cái gì đó (ngay cả khi nó chỉ là 1 hướng dẫn). –

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