कर्नेल में कौन सी फ़ाइल फोर्क (), vfork () ... sys_clone () सिस्टम कॉल का उपयोग करने के लिए निर्दिष्ट करती है


9

जब सिस्टम कॉल को ट्रेस करने के लिए ltrace का उपयोग किया जाता है, मैं देख सकता था कि fork () sys_fone () के बजाय sys_clone () का उपयोग करता है। लेकिन मैं लिनक्स स्रोत को नहीं खोज सका जहां इसे परिभाषित किया गया है।

मेरा कार्यक्रम है

#include<stdio.h>
main()
{
        int pid,i=0,j=0;
        pid=fork();
        if(pid==0)
                printf("\nI am child\n");
        else
                printf("\nI am parent\n");

}

और ltrace आउटपुट है

SYS_brk(NULL)                                                                               = 0x019d0000
SYS_access("/etc/ld.so.nohwcap", 00)                                                        = -2
SYS_mmap(0, 8192, 3, 34, 0xffffffff)                                                        = 0x7fe3cf84f000
SYS_access("/etc/ld.so.preload", 04)                                                        = -2
SYS_open("/etc/ld.so.cache", 0, 01)                                                         = 3
SYS_fstat(3, 0x7fff47007890)                                                                = 0
SYS_mmap(0, 103967, 1, 2, 3)                                                                = 0x7fe3cf835000
SYS_close(3)                                                                                = 0
SYS_access("/etc/ld.so.nohwcap", 00)                                                        = -2
SYS_open("/lib/x86_64-linux-gnu/libc.so.6", 0, 00)                                          = 3
SYS_read(3, "\177ELF\002\001\001", 832)                                                     = 832
SYS_fstat(3, 0x7fff470078e0)                                                                = 0
SYS_mmap(0, 0x389858, 5, 2050, 3)                                                           = 0x7fe3cf2a8000
SYS_mprotect(0x7fe3cf428000, 2097152, 0)                                                    = 0
SYS_mmap(0x7fe3cf628000, 20480, 3, 2066, 3)                                                 = 0x7fe3cf628000
SYS_mmap(0x7fe3cf62d000, 18520, 3, 50, 0xffffffff)                                          = 0x7fe3cf62d000
SYS_close(3)                                                                                = 0
SYS_mmap(0, 4096, 3, 34, 0xffffffff)                                                        = 0x7fe3cf834000
SYS_mmap(0, 4096, 3, 34, 0xffffffff)                                                        = 0x7fe3cf833000
SYS_mmap(0, 4096, 3, 34, 0xffffffff)                                                        = 0x7fe3cf832000
SYS_arch_prctl(4098, 0x7fe3cf833700, 0x7fe3cf832000, 34, 0xffffffff)                        = 0
SYS_mprotect(0x7fe3cf628000, 16384, 1)                                                      = 0
SYS_mprotect(0x7fe3cf851000, 4096, 1)                                                       = 0
SYS_munmap(0x7fe3cf835000, 103967)                                                          = 0
__libc_start_main(0x40054c, 1, 0x7fff47008298, 0x4005a0, 0x400590 <unfinished ...>
fork( <unfinished ...>
SYS_clone(0x1200011, 0, 0, 0x7fe3cf8339d0, 0)                                               = 5967
<... fork resumed> )                                                                        = 5967
puts("\nI am parent" <unfinished ...>
SYS_fstat(1, 0x7fff47008060)                                                                = 0
SYS_mmap(0, 4096, 3, 34, 0xffffffff
)                                                        = 0x7fe3cf84e000
I am child
SYS_write(1, "\n", 1
)                                                                       = 1
SYS_write(1, "I am parent\n", 12)                                                           = -512
--- SIGCHLD (Child exited) ---
SYS_write(1, "I am parent\n", 12I am parent
)                                                           = 12
<... puts resumed> )                                                                        = 13
SYS_exit_group(13 <no return ...>
+++ exited (status 13) +++

यह आपके लिए मददगार हो सकता है: lxr.linux.no/linux+v3.10.9
रीप्ले

@ mauro.stettler मैं इसे lxr में नहीं पा सका
user3539

क्या आपका मतलब है git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/… रेखा के आसपास 1700? आप क्या पता लगाने की उम्मीद कर रहे थे?
msw

जवाबों:


29

fork()और vfork()glibc में रैपर के माध्यम से लागू किया जाता है clone()सिस्टम कॉल। बेहतर के बीच के रिश्ते को समझने के लिए fork()और clone(), हम लिनक्स में प्रक्रियाओं और धागे के बीच संबंध पर विचार करना चाहिए।

परंपरागत रूप से, fork()मूल प्रक्रिया के स्वामित्व वाले सभी संसाधनों को अलग कर देगा और प्रतिलिपि को बाल प्रक्रिया को सौंप देगा। यह दृष्टिकोण काफी हद तक खत्म हो जाता है, जो सभी के लिए हो सकता है अगर बच्चा तुरंत फोन करता है exec()। लिनक्स में, माता-पिता और बच्चे की प्रक्रियाओं के बीच साझा किए जाने वाले डेटा की प्रतिलिपि बनाने में देरी या पूरी तरह से कॉपी -ऑन-लिखने वाले पृष्ठों fork()का उपयोग करता है। इस प्रकार, सामान्य के दौरान होने वाला एकमात्र ओवरहेड बच्चे के लिए माता-पिता के पृष्ठ तालिकाओं की नकल और एक अनूठी प्रक्रिया विवरणक संरचना का कार्य है ।fork()task_struct

लिनक्स थ्रेड्स के लिए एक असाधारण दृष्टिकोण भी लेता है। लिनक्स में, थ्रेड्स केवल सामान्य प्रक्रियाएं हैं जो कुछ संसाधनों को अन्य प्रक्रियाओं के साथ साझा करने के लिए होती हैं। यह विंडोज या सोलारिस जैसे अन्य ऑपरेटिंग सिस्टम की तुलना में थ्रेड्स के लिए एक मौलिक रूप से अलग दृष्टिकोण है, जहां प्रक्रियाएं और धागे पूरी तरह से अलग-अलग प्रकार के जानवर हैं। लिनक्स में, प्रत्येक थ्रेड का अपना एक साधारण task_structहोता है जो बस इस तरह से सेटअप होता है कि यह कुछ संसाधनों को साझा करता है, जैसे कि अभिभावक प्रक्रिया के साथ।

flagsके पैरामीटर clone()सिस्टम कॉल झंडे जो जो संसाधनों से संकेत मिलता है, यदि कोई हो, माता-पिता और बच्चे प्रक्रियाओं साझा करना चाहिए का एक सेट भी शामिल है। प्रक्रियाओं और धागे दोनों के माध्यम से बनाया जाता है clone(), केवल अंतर झंडे का सेट होता है जिसे पारित किया जाता है clone()

एक सामान्य के fork()रूप में लागू किया जा सकता है:

clone(SIGCHLD, 0);

यह एक कार्य बनाता है जो अपने माता-पिता के साथ किसी भी संसाधन को साझा नहीं करता है, और SIGCHLDजब यह बाहर निकलता है, तो माता-पिता को समाप्ति संकेत भेजने के लिए सेट किया जाता है।

इसके विपरीत, एक कार्य जो अभिभावक के साथ एड्रेस स्पेस, फाइलसिस्टम रिसोर्सेस, फाइल डिस्क्रिप्टर और सिग्नल हैंडलर्स को साझा करता है, दूसरे शब्दों में एक थ्रेड के साथ बनाया जा सकता है:

clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0);

vfork()बदले में CLONE_VFORK, एक अलग ध्वज के माध्यम से कार्यान्वित किया जाता है , जो माता-पिता की प्रक्रिया को तब तक सोने का कारण बनेगा जब तक कि बच्चे की प्रक्रिया एक संकेत के माध्यम से नहीं उठती। बच्चा माता-पिता के नाम स्थान में निष्पादन का एकमात्र धागा होगा, जब तक कि वह कॉल exec()या बाहर नहीं निकलता। बच्चे को मेमोरी में लिखने की अनुमति नहीं है। संबंधित clone()कॉल इस प्रकार हो सकती है:

clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0)

का कार्यान्वयन sys_clone()वास्तुकला विशिष्ट है, लेकिन काम का बड़ा हिस्सा do_fork()परिभाषित में होता है kernel/fork.c। यह फ़ंक्शन स्टेटिक को कॉल करता है clone_process(), जो माता-पिता की नकल के रूप में एक नई प्रक्रिया बनाता है, लेकिन अभी तक इसे शुरू नहीं करता है। clone_process()रजिस्टरों को कॉपी करता है, नए कार्य के लिए एक पीआईडी ​​असाइन करता है, और क्लोन के द्वारा निर्दिष्ट प्रक्रिया पर्यावरण के उपयुक्त भागों को या तो डीबेट करता है या साझा करता है flags। जब clone_process()रिटर्न, do_clone()नई बनाई गई प्रक्रिया को जगाएगा और इसे चलाने के लिए शेड्यूल करेगा।


2
+1 clone()धागे और कांटे के संबंध में महत्व की अच्छी व्याख्या ।
गोल्डीलॉक्स

1
मेरे सभी संदेहों को साफ कर दिया
user3539

2

लिनक्स के तहत कर्नेल सिस्टम कॉल के लिए यूजरलैंड सिस्टम कॉल फ़ंक्शन के अनुवाद के लिए जिम्मेदार घटक libc है। GLibC में, NPTL लाइब्रेरी इसे clone(2)सिस्टम कॉल पर रीडायरेक्ट करती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.