2011-10-15 14 views
12

मुझे नहीं पता कि यूनिक्स के पास नई प्रक्रिया बनाने के लिए fork() क्यों है। Win32 API में हमारे पास CreateProcess() है जो एक नई प्रक्रिया बनाता है और निष्पादन योग्य को अपने पता स्थान में लोड करता है, फिर प्रवेश बिंदु से निष्पादित करना प्रारंभ करता है। हालांकि यूनिक्स एक नई प्रक्रिया बनाने के लिए कांटा प्रदान करता है, और मुझे नहीं लगता कि मैं अपनी प्रक्रिया को डुप्लिकेट क्यों करूं यदि मैं एक और प्रक्रिया चलाऊंगा।यूनिक्स का फोर्क क्यों है() लेकिन CreateProcess() नहीं?

तो मुझे इन दो सवाल पूछना है:

  1. तो fork() और फिर exec() अधिक कुशल है, क्योंकि हम fork() लगभग हर मामले में बाद exec() फोन करेगा क्यों नहीं वहाँ एक समारोह forkexec(const char *newProc) है?
  2. यदि यह अधिक कुशल नहीं है, तो fork() क्यों मौजूद है?

उत्तर

11

fork() कॉल पर्याप्त है। यह यह भी अधिक लचीला है; यह आपको प्रक्रिया बनाने के लिए सिस्टम कॉल को जटिल बनाने के बजाय, बाल प्रक्रिया में I/O पुनर्निर्देशन को समायोजित करने जैसी चीजों की अनुमति देता है। SUID या SGID प्रोग्राम के साथ, यह अनुमति देता है अन्य प्रक्रिया को निष्पादित करने से पहले बच्चे अपने ऊंचे विशेषाधिकार खोने के लिए।

यदि आप प्रक्रिया बनाने के लिए एक जटिल तरीका चाहते हैं, तो 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]); 

अंतर posix_spawnp() निष्पादन के लिए पथ पर एक खोज करता है।

posix_spawn_file_actions_t और posix_spawnattr_t प्रकारों को संभालने के लिए अन्य कार्यों का एक पूरा सेट है (संदर्भित पृष्ठ पृष्ठ के नीचे 'भी देखें' लिंक का पालन करें)।

यह विंडोज़ पर CreateProcess() जैसा थोड़ा सा है। अधिकांश भाग के लिए, हालांकि, fork() का उपयोग करके exec() शीघ्र ही आसान है।


मुझे समझ नहीं आता कि आप क्या मतलब है। बाल प्रक्रिया कोड मेरे द्वारा लिखा जाएगा, तो if (fork() == 0) लिखने और बच्चे के main() की शुरुआत में यह कोड डालने के बीच क्या अंतर है?

अक्सर, आपके द्वारा निष्पादित कोड आपके द्वारा नहीं लिखा जाता है, इसलिए आप बच्चे की प्रक्रिया की शुरुआत में क्या होता है संशोधित नहीं कर सकते हैं। एक खोल के बारे में सोचो; यदि आप शैल से चलने वाले एकमात्र कार्यक्रम हैं जिन्हें आपने लिखा है, तो जीवन बहुत गरीब हो जाएगा।

अक्सर, आपके द्वारा निष्पादित कोड को कई अलग-अलग स्थानों से बुलाया जाएगा। विशेष रूप से, एक खोल और एक कार्यक्रम के बारे में सोचें जिसे कभी-कभी पाइपलाइन में निष्पादित किया जाएगा और कभी-कभी पाइप के बिना निष्पादित किया जाएगा। बुलाया प्रोग्राम यह नहीं बता सकता कि I/O पुनर्निर्देशन और फ़िक्सअप क्या करना चाहिए; कॉलिंग प्रोग्राम जानता है।

यदि कॉलिंग प्रोग्राम उन्नत विशेषाधिकार (SUID या SGID विशेषाधिकार) के साथ चल रहा है, तो सामान्य प्रोग्राम चलाने से पहले उन 'बंद' को चालू करना सामान्य बात है। यह जानने के लिए कि क्या करना है, अन्य कार्यक्रम पर निर्भर है ... मूर्ख।

+0

मुझे समझ में नहीं आया कि आपका क्या मतलब है। बाल प्रक्रिया कोड मेरे द्वारा लिखा जाएगा तो लिखने के बीच क्या अंतर है (फोर्क() == 0) और इस कोड को बच्चे के मुख्य() की शुरुआत में डालना? –

+0

हम्म, तो आप कहते हैं कि फोर्क() - exec() जोड़े के साथ ऐसी चीजें करने के लिए यह आसान है (i/o पुनर्निर्देशन, विशेषाधिकार वापस लेना, आदि ..) क्या मुझे यह सही लगता है? –

+1

हां: 'posix_spawn()' के लिए आवश्यक contortions की तुलना में, 'exec()' का उपयोग करना बहुत आसान है और उसके बाद बच्चा 'exec()' का उपयोग करने से पहले क्रियाओं को पूरा करता है। 'Posix_spawn()' के लिए तर्क पढ़ें; यह काफी प्रबुद्ध है (या, कम से कम, यह मेरे लिए था)। 'Posix_spawn()' के साथ आप जो चीजें कर सकते हैं उसकी सूची प्रभावशाली है, लेकिन यह 'फोर्क()' प्रदान करता है उससे भी अधिक जटिल है। –

3

यूनिक्स जैसे ऑपरेटिंग सिस्टम (कम से कम नए Linux और BSD कर्नेल) आम तौर पर एक बहुत ही कुशल fork कार्यान्वयन है - यह है "इतना सस्ता" कि "पिरोया" कर रहे हैं कुछ भाषाओं में इस पर आधारित कार्यान्वयन ।

अंत में forkexec फ़ंक्शन ~ n - अनुप्रयोग कोड की एन-लाइनों के कुछ छोटे मूल्यों के लिए है।

मुझे यकीन है कि विंडोज़ इस तरह के एक उपयोगी ForkProcess :(

मुबारक कोडिंग था चाहते हैं।


एक cnicutar उल्लेख किया है, Copy-On-Write (COW) एक का उपयोग किया रणनीति है।

+2

ठीक लेकिन अगर मैं बहुत ही कुशल कांटा के बाद दूसरे में प्रक्रिया बदल सकते हैं, यह बेहतर नया बनाने के लिए नहीं है शुरुआत से प्रक्रिया? तो मुझे अपनी प्रक्रिया को डुप्लिकेट नहीं करना है। यह मुझे –

+0

@ एली वेली आधुनिक फोर्क नहीं मिला है, प्रक्रिया को डुप्लिकेट नहीं करते हैं। "लिखने पर प्रतिलिपि" देखो। – cnicutar

+0

कहता है कि मैं एक नई प्रक्रिया तैयार करूंगा। सी-ओ-डब्ल्यू या नहीं, कांटा कुछ सही करता है? तो मुझे लगता है कि अगर मैं सिर्फ एक नई प्रक्रिया बनाउंगा, तो मैं ऐसा कुछ नहीं करूंगा (भले ही यह केवल 1 निर्देश है)। –