هل تسفر Waitpid عن معلومات الحالة صالحة لعملية الطفل التي خرجت بالفعل؟

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

  •  30-09-2019
  •  | 
  •  

سؤال

اذا انا fork عملية الطفل ، وتخرج عملية الطفل قبل استدعاء الوالد waitpid, ، إذن هي معلومات حالة الخروج التي يتم تعيينها بواسطة waitpid لا تزال صالحة؟ إذا كان الأمر كذلك ، متى يصبح غير صالح ؛ أي كيف يمكنني التأكد من أنني أتمكن من الاتصال waitpid على PID الطفل واستمر في الحصول على معلومات حالة الخروج صالحة بعد فترة زمنية تعسفية ، وكيف يمكنني "التنظيف" (أخبر نظام التشغيل أنني لم أعد مهتمًا بمعلومات حالة الخروج لعملية الطفل النهائية)؟

كنت ألعب مع الكود التالي ، ويبدو أن معلومات حالة الخروج صالحة لبضع ثوان على الأقل بعد انتهاء الطفل ، لكنني لا أعرف كم من الوقت أو كيفية إبلاغ نظام التشغيل الذي لن أكون عليه الدعوة waitpid تكرارا:

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{
    pid_t pid = fork();

    if (pid < 0) {
        fprintf(stderr, "Failed to fork\n");
        return EXIT_FAILURE;
    }
    else if (pid == 0) { // code for child process
        _exit(17);
    }
    else { // code for parent
        sleep(3);

        int status;
        waitpid(pid, &status, 0);
        waitpid(pid, &status, 0); // call `waitpid` again just to see if the first call had an effect
        assert(WIFEXITED(status));
        assert(WEXITSTATUS(status) == 17);
    }

    return EXIT_SUCCESS;
}
هل كانت مفيدة؟

المحلول

نعم، waitpid سيعمل بعد خروج الطفل. سيبقي نظام التشغيل إدخال عملية الطفل في جدول العملية (بما في ذلك حالة الخروج) حتى يتصل الأصل waitpid (أو آخر waitوظيفة العائلة) أو حتى يخرج الوالد (عند هذه النقطة يتم جمع الحالة بواسطة init معالجة). هذا هو ما هي عملية "Zombie": عملية خرجت من قبل لا تزال مقيمة في جدول العملية لهذا الغرض بالضبط.

يجب أن يختفي إدخال العملية في الجدول بعد المكالمة الأولى waitpid. أظن أن السبب في أنك في مثالك يبدو أنك قادر على الاتصال waitpid مرتين ببساطة بسبب waitpid لن يعدل status حجة إذا pid لم يعد موجودا. لذلك يجب أن تعمل المكالمة الأولى وتملأ status, ، ويجب أن تكون المكالمة الثانية هي إرجاع رمز الخطأ وعدم التغيير status. يمكنك التحقق من ذلك من خلال فحص قيم إرجاع waitpid المكالمات و/أو استخدام اثنين مختلفين status المتغيرات.

نصائح أخرى

يحافظ نظام التشغيل على إنهاء العملية في أ ولاية غيبوبة حتى والدها (والتي قد تكون init إذا تم إنهاء عملية الوالد الأصلية سابقًا) تجمع حالة الخروج هذه wait(2) استدعاء النظام. لذا فإن الجواب هو - حالة خروج العملية لا يصبح غير صالح.

نعم.

من صفحة الرجل:

الطفل الذي ينتهي ، ولكن لم يتم انتظاره يصبح "غيبوبة". تحافظ kernel على الحد الأدنى من المعلومات حول عملية الزومبي (PID ، حالة الإنهاء ، معلومات استخدام الموارد) من أجل السماح للوالد بإجراء انتظار لاحقًا للحصول على معلومات حول الطفل.

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