كيفية الانتظار حتى جميع العمليات التابعة دعا اليه شوكة) إكمال (؟

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

سؤال

وأنا التفرع عدد من العمليات وأريد لقياس الوقت الذي يستغرقه لإكمال المهمة بأكملها، وهذا هو عندما يتم الانتهاء من جميع العمليات متشعب. يرجى تقديم المشورة كيفية جعل الانتظار عملية الأصل حتى يتم إنهاء كافة العمليات التابعة؟ أريد التأكد من أنني إيقاف الموقت في اللحظة المناسبة.

وهنا ك a رمز يمكنني استخدام:

#include <iostream>
#include <string>
#include <fstream>
#include <sys/time.h>
#include <sys/wait.h>

using namespace std;

struct timeval first,  second,  lapsed;
struct timezone tzp; 

int main(int argc, char* argv[])// query, file, num. of processes.
{

    int pCount = 5; // process count

    gettimeofday (&first, &tzp); //start time

    pid_t* pID = new pid_t[pCount];

    for(int indexOfProcess=0; indexOfProcess<pCount; indexOfProcess++)
    {
        pID[indexOfProcess]= fork();

        if (pID[indexOfProcess] == 0)                // child
        {
            // code only executed by child process

            // magic here

            // The End
            exit(0);
        }
        else if (pID[indexOfProcess] < 0)    // failed to fork
        {
            cerr << "Failed to fork" << endl;
            exit(1);
        }
        else                         // parent
        {
            // if(indexOfProcess==pCount-1) and a loop with waitpid??

            gettimeofday (&second, &tzp); //stop time
            if (first.tv_usec > second.tv_usec)
            {
                second.tv_usec += 1000000;
                second.tv_sec--;
            }

            lapsed.tv_usec = second.tv_usec - first.tv_usec;
            lapsed.tv_sec = second.tv_sec - first.tv_sec; 

            cout << "Job performed in " <<lapsed.tv_sec << " sec and " << lapsed.tv_usec    << " usec"<< endl << endl;

        }

    }//for

}//main
هل كانت مفيدة؟

المحلول

وكنت تحرك كل شيء بعد السطر "آخر // الأم" لأسفل، خارج عن الحلقة. بعد حلقة من الشوك، لا آخر للحلقة مع waitpid، ثم توقف على مدار الساعة وتفعل بقية:

for (int i = 0; i < pidCount; ++i) {
    int status;
    while (-1 == waitpid(pids[i], &status, 0));
    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
        cerr << "Process " << i << " (pid " << pids[i] << ") failed" << endl;
        exit(1);
    }
}

gettimeofday (&second, &tzp); //stop time

ولقد افترض أنه إذا فشل عملية تابعة للخروج عادة مع حالة 0، فإنه لم يكمل عمله، وبالتالي اختبار فشلت في إنتاج البيانات توقيت صالحة. من الواضح إذا كانت العمليات التابعة ل<م> من المفترض إلى أن قتل على يد إشارات، أو الأوضاع خروج غير 0 العودة، ثم سيكون لديك لتغيير الاختيار الخطأ وفقا لذلك.

وبديل باستخدام الانتظار:

while (true) {
    int status;
    pid_t done = wait(&status);
    if (done == -1) {
        if (errno == ECHILD) break; // no more child processes
    } else {
        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
            cerr << "pid " << done << " failed" << endl;
            exit(1);
        }
    }
}

وهذا واحد لا اقول لكم أي عملية في تسلسل فشلت، ولكن إذا كنت تهتم بعد ذلك يمكنك إضافة رمز إلى البحث عنه في مجموعة PIDS ونعود المؤشر.

نصائح أخرى

وأبسط طريقة للقيام

while(wait() > 0) { /* no-op */ ; }

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

int status;
[...]
do {
    status = wait();
    if(status == -1 && errno != ECHILD) {
        perror("Error during wait()");
        abort();
    }
} while (status > 0);

وانظر أيضا صفحة wait(2) دليل.

ودعوة الانتظار (أو waitpid) في حلقة حتى يتم احتساب جميع الأطفال.

في هذه الحالة، جميع العمليات تتم مزامنة على أي حال، ولكن في الانتظار العام ويفضل عندما المزيد من العمل يمكن القيام به (على سبيل المثال تجمع العملية المنفذة)، لأنه سيعود عندما أول التغييرات المتاحة حالة العملية.

وأعتقد أن rel="nofollow الانتظار استدعاء نظام سوف تنجز ما كنت تبحث عنه.

for (int i = 0; i < pidCount; i++) {
    while (waitpid(pids[i], NULL, 0) > 0);
}

وانها لن تنتظر بالترتيب الصحيح، ولكنها سوف تتوقف بعد وقت قصير من وفاة الطفل الماضي.

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