ऐसा प्रतीत होता है कि clone()
लिनक्स 2.6 में दो चीजें घूम रही हैं
एक सिस्टम कॉल है:
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
ऐसा करने से वर्णित "क्लोन ()" है man 2 clone
।
यदि आप उस आदमी पृष्ठ को पर्याप्त रूप से पढ़ते हैं, तो आप इसे देखेंगे:
It is actually a library function layered on top of the
underlying clone() system call.
जाहिर है, आप "लाइब्रेरी फ़ंक्शन" का उपयोग करके थ्रेडिंग को लागू करने वाले हैं, जो कि भ्रमवश पहचाने जाने वाले सिस्टम कॉल पर आधारित है।
मैंने एक छोटा कार्यक्रम लिखा:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int ac, char **av)
{
pid_t cpid;
switch (cpid = fork()) {
case 0: // Child process
break;
case -1: // Error
break;
default: // parent process
break;
}
return 0;
}
इसके साथ संकलित: c99 -Wall -Wextra
और यह strace -f
देखने के लिए भाग गया कि सिस्टम कॉलिंग वास्तव में क्या करती है। मुझे यह strace
एक लिनक्स 2.6.18 मशीन (x86_64 CPU) पर मिला:
20097 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b4ee9213770) = 20098
20097 exit_group(0) = ?
20098 exit_group(0)
strace
आउटपुट में कोई "कांटा" कॉल दिखाई नहीं देता है । आउटपुट में दिखाई जाने वाली clone()
कॉल strace
में मैन-पेज-क्लोन से बहुत अलग तर्क होते हैं। child_stack=0
जैसा कि पहले तर्क से अलग है int (*fn)(void *)
।
ऐसा प्रतीत होता है कि fork(2)
सिस्टम कॉल को वास्तविक रूप में लागू किया जाता है clone()
, ठीक उसी तरह जैसे "लाइब्रेरी फंक्शन" clone()
को लागू किया जाता है। वास्तविक clone()
मानव पेज क्लोन से तर्क का एक अलग सेट है।
सरल रूप से, आपके दोनों स्पष्ट रूप से विरोधाभासी बयान fork()
और clone()
सही हैं। शामिल "क्लोन" अलग है, यद्यपि।