كيف يمكنني تفريخ شيطان في Uclinux باستخدام Vfork؟

StackOverflow https://stackoverflow.com/questions/3893293

  •  28-09-2019
  •  | 
  •  

سؤال

سيكون هذا سهلاً مع Fork () ، لكن ليس لدي MMU. لقد سمعت أن Vfork () يحجب عملية الوالدين حتى يخرج الطفل أو ينفذ exec (). كيف يمكنني إنجاز شيء كهذا؟:

pid_t pid = vfork();

if (pid == -1) {
    // fail
    exit(-1);
}

if (pid == 0) {
    // child
    while(1) {
        // Do my daemon stuff
    }

    // Let's pretend it exits sometime
    exit();
} 

// Continue execution in parent without blocking.....
هل كانت مفيدة؟

المحلول

يبدو أنه لا توجد طريقة للقيام بذلك تمامًا كما لديك هنا. exec أو _exit يجب أن يتم استدعاء الوالد لمواصلة التنفيذ. إما وضع رمز الخفي في آخر قابل للتنفيذ و exec أو استخدام الطفل لتفرخ المهمة الأصلية. النهج الثاني هو الطريقة المتستر ، ويتم وصفها هنا.

نصائح أخرى

وظيفة Daemon () لأنظمة Uclinux بدون MMU و Fork () ، بواسطة Jamie Lokier ، بتنسيق التصحيح

لا يمكنك عمل Daemon () مع Vfork (). لإنشاء شيء مشابه لخفي على! MMU باستخدام Vfork () ، لا تموت العملية الوالدية (لذلك هناك عمليات إضافية) ، ويجب عليك الاتصال بالخفي على الخلفية (أي عن طريق إلحاقها وإلى سطر الأوامر على الصدف).

من ناحية أخرى ، يوفر Linux Clone (). مسلحًا بذلك ، والمعرفة والرعاية ، من الممكن تنفيذ Daemon () لـ! MMU. لدى جيمي لوكير وظيفة للقيام بذلك على ARM و I386 ، احصل عليه من هنا.

يحرر: صنع الرابط إلى Daemon's Daemon () لـ Jamie Lokier لـ! MMU Linux أكثر بروزًا.

كنت أعتقد أن هذا سيكون نوعًا من المشكلة التي واجهها العديد من الآخرين من قبل ، لكنني واجهت صعوبة في العثور على أي شخص يتحدث عن مشاكل "قتل الوالد".

اعتقدت في البداية أنك يجب أن تكون قادرًا على القيام بذلك باستخدام دعوة بسيطة (ليس كذلك ، ولكن نوعًا ما) clone, ، مثله:

pid_t new_vfork(void) {
    return clone(child_func,        /* child function */
                 child_stack,          /* child stack    */
                 SIGCHLD | CLONE_VM,   /* flags */
                 NULL,                 /* argument to child */
                 NULL,                 /* pid of the child */
                 NULL,                 /* thread local storage for child */
                 NULL);                /* thread id of child in child's mem */
}

باستثناء أن تحديد child_stack و child_func من العمل بالطريقة التي يحدث بها مع Vfork أمر صعب للغاية لأن Child_func يجب أن يكون عنوان الإرجاع من استدعاء Clone و Child_stack يجب أن يكون الجزء العلوي من المكدس عند النقطة يتم إجراء استدعاء النظام الفعلي (sys_clone).

ربما يمكنك محاولة الاتصال sys_clone مباشرة مع

pid_t new_vfork(void) {
    return sys_clone( SIGCHLD | CLONE_VM, NULL);
}

الذي أعتقد أنه قد يحصل على ما تريد. إن تمرير الوسيطة الثانية ، وهو مؤشر child_stack ، يؤدي إلى أن يفعل kernel نفس الشيء كما هو الحال في Vfork و Fork ، وهو استخدام نفس المكدس مثل الوالد.

لم أستخدمها أبدًا sys_clone مباشرة ولم تختبر هذا ، لكنني أعتقد أنه يجب أن ينجح. أعتقد أن:

  sys_clone( SIGCHLD | CLONE_VM | CLONE_VFORK, NULL);

يعادل vfork.

إذا لم ينجح هذا (ولا يمكنك معرفة كيفية القيام بشيء مماثل) ، فقد تتمكن من استخدام مكالمة الاستنساخ العادية مع setjump و longjmp مكالمات لمحاكاة ذلك ، أو قد تكون قادرًا على الالتزام بالحاجة إلى دلالات "العودة مرتين" fork و vfork.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top