سؤال

أحاول القيام بمهمة لأحد فصولي الدراسية ولم يتصل بي أي من الأساتذة أو زملائي.لذا قبل أن تجيب، من فضلك لا تعطيني أي إجابات محددة!تفسيرات فقط!

ما يجب علي فعله هو كتابة برنامج c (timeout.c) يأخذ وسيطتين لسطر الأوامر، W وT، حيث W هو مقدار الوقت بالثواني الذي يجب أن تستغرقه العملية الفرعية قبل الخروج، وT هو مقدار الوقت يجب أن تنتظر العملية الأصلية العملية الفرعية، قبل إنهاء العملية الفرعية وطباعة رسالة "انتهاء المهلة".في الأساس، إذا كان W > T، فيجب أن تكون هناك مهلة.وإلا، يجب على الطفل إنهاء عمله ومن ثم لا تتم طباعة رسالة المهلة.

ما أردت فعله هو جعل العملية الرئيسية في وضع السكون لمدة T ثانية، ثم إنهاء العملية الفرعية وطباعة المهلة، ولكن طباعة رسالة المهلة لن تحدث في كلتا الحالتين.كيف يمكنني التحقق من إنهاء العملية الفرعية؟لقد طُلب مني استخدام إنذار() لهذا، ولكن ليس لدي أي فكرة عن الاستخدام الذي يمكن أن تخدمه هذه الوظيفة.

إليك الكود الخاص بي في حال أراد أي شخص إلقاء نظرة:

void handler (int sig) {
    return;
}

int main(int argc, char* argv[]){
    if (argc != 3) {
    printf ("Please enter values W and T, where W\n");
    printf ("is the number of seconds the child\n");
    printf ("should do work for, and T is the number\n");
    printf ("of seconds the parent process should wait.\n");
    printf ("-------------------------------------------\n");
    printf ("./executable <W> <T>\n");
    }

    pid_t pid;
    unsigned int work_seconds = (unsigned int) atoi(argv[1]);
    unsigned int wait_seconds = (unsigned int) atoi(argv[2]);

    if ((pid = fork()) == 0) {
        /* child code */
        sleep(work_seconds);
        printf("Child done.\n");
        exit(0);
    }

    sleep(wait_seconds);
    kill(pid, SIGKILL);
    printf("Time out.");

    exit(0);
}
هل كانت مفيدة؟

المحلول

على الرغم من أن Waitpid سيحصل على حالة عودة الطفل، فإن الاستخدام الافتراضي ستجبر الوالدين على الانتظار حتى ينتهي الطفل.

ولكن الاحتياجات الخاصة بك (إذا فهمت بشكل صحيح) فقط يريد الوالد أن ينتظر وقتا معينا، ويمكن استخدام المنبه () للقيام بذلك.

بعد ذلك، يجب عليك استخدام WATEPID () مع خيار محدد يعود على الفور إذا لم يتم إخراج الطفل بعد (قم بدراسة معلمات API).لذلك إذا لم يخرج الطفل، فيمكنك قتله، وإلا فإنك تتلقى بالفعل حالة العودة.

نصائح أخرى

تريد timeout ليتوقف البرنامج أكثر أو أقل بمجرد انتهاء الأمر، لذلك إذا قلت timeout -t 1000 sleep 1 يتوقف برنامج الحماية بعد حوالي ثانية واحدة، وليس بعد 1000 ثانية.

الطريقة للقيام بذلك هي ضبط منبه من نوع ما - بشكل كلاسيكي، باستخدام alarm() استدعاء النظام ومعالج الإشارة لـ SIGALRM - ثم قم بتنفيذ العملية الرئيسية wait() أو waitpid() بحيث عندما يموت الطفل يستيقظ ويجمع الجثة.إذا تلقت عملية الوالدين إشارة إنذار، فيمكنها طباعة رسالتها وإرسال تهديدات بالقتل من نوع ما إلى طفلها.قد يكون من المعقول تجربة SIGTERM و/أو SIGHUP قبل اللجوء إلى SIGKILL؛تعطي إشارات SIGTERM وSIGHUP للطفل الضال فرصة للتنظيف بينما لا تفعل ذلك SIGKILL.

إذا كنت تعرف كيفية إدارة الإشارات، فيمكنك التقاط Sigalrm و Sigchld في عملية الأصل الخاصة بك.سيتم رفع Sigchld عندما ينتهي العميل، و Sigalrm عند انتهاء الوقت المناسب.إذا كانت الإشارة المرفوعة الأولى هي Sigalrm، انتهت المهلة، وإلا، إذا كانت الإشارة الأولى إلى أن المصيد الوالد هو SIGCHLD، فقد توقف الطفل قبل انتهاء المهلة.

انتظر () أو waitpid () لا يزال من الضروري جمع الطفل المنتهي.

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