2013-02-12 38 views
14

Có vẻ như là hai cách phổ biến của chạy một thực thi bên ngoài từ C trong unix, cácvào hệ thống() hoặc fork()/exec()?

system() 

cuộc gọi và

pid = fork() 
switch(pid) 
//switch statement based on return value of pid, 
//one branch of which will include and exec() command 

Có lý do nào để thích một ngã ba/exec trên hệ thống trong trường hợp chúng tương đương về mặt chức năng (quá trình cha mẹ chờ trẻ kết thúc, không có thông tin phức tạp nào được trả về từ trẻ) ?.

Trả lời

18

system thực thi trình thông dịch lệnh, tức là trình bao (a) chậm hơn lệnh rẽ nhánh trực tiếp, (b) có thể hoạt động khác nhau trên các hệ thống khác nhau và (c) là nguy cơ bảo mật tiềm ẩn. một chuỗi từ một nguồn không tin cậy. Ngoài ra, system chờ quá trình con thoát, trong khi bạn có thể muốn nó chạy đồng thời với quy trình gốc.

khác ở chung, ở mức độ thấp ngã ba/exec cung cấp cho bạn kiểm soát bổ sung: trước hoặc ở giữa hai cuộc phẫu thuật, bạn có thể muốn chdir, mở đường ống, gần mô tả tập tin, thiết lập bộ nhớ chia sẻ vv

(Theo các hệ thống khác nhau, tôi không có nghĩa là Windows và Unix (như Windows thậm chí không có ngã ba): Tôi đang nói Red Hat Linux so với Ubuntu, trước đây sử dụng Bash để thực hiện những gì được chuyển đến system, sau này là một vỏ tương thích POSIX nhẹ.)

+0

Tôi hỏi prof của tôi sự khác biệt là gì và anh ấy nói 'system()' là một API cho hệ điều hành và 'fork/exec' là các cuộc gọi cấp hệ thống. Điều này có đúng không? Sự hiểu biết của tôi là các API cho hệ điều hành an toàn hơn theo nghĩa là chúng có thể chứa kiểm tra bổ sung, trái ngược với các cuộc gọi hệ thống. – Celeritas

+2

@Celeritas Theo nghĩa nào đó (các cuộc gọi hệ thống cũng là các API hệ điều hành), nhưng kết luận của bạn là sai, như tôi đã lập luận trong câu trả lời. 'system' không thêm kiểm tra; nó thêm chức năng không được kiểm soát. –

0

hệ thống() sẽ loại bỏ lệnh và thực hiện nó như người dùng đã nhập. tôi hầu như đã thấy nó như system("pause"); system("cls");

Nhưng nếu bạn cần kiểm soát quá trình con, bạn muốn ngã ba.

+5

'system (" pause ");' là một căn bệnh! Nó giống như cách hiệu quả nhất để làm cho chương trình của bạn chờ người dùng gõ một cái gì đó. –

+0

@JohnZwinck nó đủ tốt cho đại học :) thường ở đó để làm cho bảng điều khiển 'ở đó' khi chương trình sắp thoát ra. – Shark

+1

Lần sau, hãy thử một cái gì đó như 'cin >> dummy;' (hoặc scanf()). Và đừng nghĩ rằng công việc có tiêu chuẩn cao hơn so với trường học! –

1

Đi qua system() bổ sung thêm quá trình vỏ, có thể không phải là thứ bạn muốn.

Quy trình gọi cũng chỉ được thông báo khi vỏ đó chết không khi quá trình thực tế do vỏ bị chết.

3

fork() tạo quy trình mới. Nếu bạn không cần làm điều đó, chỉ cần sử dụng system() (hoặc popen()). Bạn có thể muốn có một quy trình thứ hai để đạt được tính song song, hoặc để kiểm soát tốt hơn công việc, nhưng thường bạn không quan tâm đến điều đó nếu công việc có nghĩa là đồng bộ.

Mặt khác, tôi thấy rằng 95% sử dụng system() là không cần thiết hoặc bằng cách nào đó sẽ được thực hiện tốt hơn theo cách khác (ví dụ: sử dụng zlib thay vì system("gzip")). Vì vậy, có lẽ câu trả lời tốt nhất là sử dụng không!

+0

trong trường hợp này là một công cụ tùy chỉnh được xây dựng bởi người khác, vì vậy tôi đã hoặc phải refactor mã của họ vào một thư viện, gọi nó thông qua sys hoặc exec, hoặc sao chép trên một đoạn mã nguồn vào nhị phân của riêng tôi. Đó là một sự lựa chọn khó khăn giữa tốc độ thực hiện bảo trì. – Sparky

+1

Chỉ để hoàn thành, có một lựa chọn khác: sử dụng ngôn ngữ cấp cao hơn như Python để gọi công cụ của bên thứ ba này và cũng đóng vai trò là "chính()" cho mã của riêng bạn. Đó là, phơi bày logic của riêng bạn như một thư viện hoặc thực thi, và sử dụng một kịch bản của một số loại để kết nối các mảnh với nhau, chứ không phải là bắn phá từ C. Thực phẩm cho tư tưởng. –

+2

Cả hai hệ thống() và popen() thực sự tạo ra hai quy trình mới - một cho shell và một cho lệnh được thực thi bên trong shell. – pelya

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