Clone (فراخوان سیستمی)
این مقاله، Clone (فراخوان سیستمی)، اخیراً بهواسطهٔ فرایند ایجاد مقاله ایجاد شدهاست. بازبینیکننده در حال بستن درخواست است و این برچسب احتمالاً بهزودی برداشته میشود.
ابزارهای بازبینی: پیشبارگیری بحث اعلان به نگارنده |
خطای اسکریپتی: پودمان «AfC submission catcheck» وجود ندارد. در مباحث سیستمعامل وقتی یک پردازه منشعب (به انگلیسی: clone) میشود، پردازه مورد نظر یک کپی از خودش ایجاد میکند. در سیستمعاملهای شبه یونیکس این کار با استفاده از چند فراخوان سیستمی مانند ()fork و ()clone و clone3() انجام میشود. پردازه اصلی که clone() را صدا میزند پردازه پدر نامیده میشود و پردازه جدیدی که ایجاد شده پردازه فرزند نامیده میشود.
این فراخوان سیستمی فرایند، بسیار مشابه فراخوان سیستمی Fork است، ولی بر خلاف ()fork دستور ()clone اجازه میدهد که بخشی از زمینهٔ اجرا در پردازه فرزند و پردازه والد مشترک باشد[۱] ، مانند virtual address space, جدول توصیفگر پرونده ها و جدول signal handlers.
تفاوت دستورات ()clone و ()clone3[ویرایش]
در طول زمان، به تعداد پرچم های ورودی موردنیاز افزوده شد، بسیاری از آنها تعیین میکردند که پردازه فرزند با پردازه والد در چه منابع و فضاهای نامی مشترک شود. در واقع، تعداد این پرچم ها آنقدر زیاد شد که وقتی پرچم CLONE_PIDFD
به نسخه 5.2 هسته لینوکس اضافه شد، آخرین بیت مجاز (بیت ۳۲ ام) برای clone گرفته شد، و دیگر اضافه کردن پرچم دیگری به دستور clone ممکن نبود.
برای اضافه کردن دستورات جدید، لازم بود تا دستورات دیگری ساخته شود تا بتواند پرچم های بیشتری را ورودی بگیرد، برای همین دستور ()clone3 ساخته شد (برای افراد کنجکاو ، یک ()clone2 وجود دارد که به نظر می رسد فقط مورد توجه معماری ia64 باشد)
ساختار دستور ()clone3 به این شکل است:
struct clone_args
{
u64 flags;
int *pidfd;
int *child_tid;
int *parent_tid;
int exit_signal;
unsigned long stack;
unsigned long stack_size;
unsigned long tls;
};
int clone3(struct clone_args *args, size_t size);
ساختار clone_args
شامل اطلاعات مورد نیاز برای انجام این فراخوان سیستمی است، flags در این ساختار در همه معماری ها ۶۴ بیتی شده است و امکان اضافه کردن تعداد قابل قبولی از پرچم های جدید در این دستور وجود دارد. برای همین این ساحتار تا زمان قابل قبولی قابل استفاده است.
برای اینکه از تکرار تابع های با نام متفاوت ولی با کار یکسان جلوگیری شود، دستور clone3 یک ورودی به نام size
نیز میگیرد که که اگر در نسخه های آینده هسته لینوکس نیاز به تغییر این ساختار پیدا شد (برای مثال باز هم نیاز به پرچم های بیشتری وجود داشت) با بررسی ورودی size بتوان تشخیص داد که منظور کاربر کدام ساختار بوده است و اجرای خواسته کاربر ممکن باشد. با این کار احتمالاً نیازی به ساخت تابع clone4 در زمان نزدیک وجود نخواهد داشت.[۲]
مثال از دستور ()clone[ویرایش]
// We have to define the _GNU_SOURCE to get access to clone(2) and the CLONE_*
// flags from sched.h
//
// Eli Bendersky [http://eli.thegreenplace.net]
// This code is in the public domain.
#define _GNU_SOURCE
#include <sched.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int child_func(void *arg)
{
char *buf = (char *)arg;
printf("Child sees buf = \"%s\"\n", buf);
strcpy(buf, "hello from child");
return 0;
}
int main(int argc, char **argv)
{
// Allocate stack for child task.
const int STACK_SIZE = 65536;
char *stack = (char *)malloc(STACK_SIZE);
if (!stack)
{
perror("malloc");
exit(1);
}
// When called with the command-line argument "vm", set the CLONE_VM flag on.
unsigned long flags = 0;
if (argc> 1 && !strcmp(argv[1], "vm"))
{
flags |= CLONE_VM;
}
char buf[100];
strcpy(buf, "hello from parent");
if (clone(child_func, stack + STACK_SIZE, flags | SIGCHLD, buf) == -1)
{
perror("clone");
exit(1);
}
int status;
if (wait(&status) == -1)
{
perror("wait");
exit(1);
}
printf("Child exited with status %d. buf = \"%s\"\n", status, buf);
return 0;
}
منابع[ویرایش]
This article "Clone (فراخوان سیستمی)" is from Wikipedia. The list of its authors can be seen in its historical and/or the page Edithistory:Clone (فراخوان سیستمی). Articles copied from Draft Namespace on Wikipedia could be seen on the Draft Namespace of Wikipedia and not main one.