C भाषा मा wait फङ्क्शन | प्रयोग, zombie रोकथाम, waitpid भिन्नता

目次

1. परिचय

सी भाषा प्रणाली कार्यक्रम र एम्बेडेड सिस्टम विकासमा व्यापक रूपमा प्रयोग हुन्छ, र त्यसमा पनि प्रोसेस व्यवस्थापन एक महत्वपूर्ण विषय हो। यस लेखमा, सी भाषा मा 「wait फङ्क्शन」 को बारेमा व्याख्या गर्नेछौं।wait फङ्क्शन प्रक्रिया बीचको समक्रमण हासिल गर्न प्रयोग हुने सिस्टम कल हो, विशेष गरी सन्तान प्रोसेसको समाप्ति पर्खनमा सहयोगी हुन्छ।

यस लेखमार्फत, wait फङ्क्शनको आधारभूत प्रयोगदेखि उन्नत विधिहरू, सम्बन्धित विषयहरू(उदाहरण: waitpid फङ्क्शन र जम्बी प्रोसेस समाधान)सम्म, व्यापक रूपमा सिक्न सक्नुहुन्छ।

2. C gengo को wait kansū के हो?

wait kansū को gaiyō

wait kansū UNIX-kei shisutemu ma upayog garine shisutemu kōru ko ek ho, ra oya purosesu le ko purosesu ko shūryō ko mātsu garna prayog garincha. Isko dwārā, oya purosesu le ko purosesu ko shūryō status pāuna sakcha.

kihonteki na dōsa

wait kansū tala dekhiyeko jastai prayog garincha.

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
    pid_t pid = fork();
    if (pid > 0) {
        // मूल प्रक्रिया
        wait(NULL); // उप प्रक्रिया समाप्त हुने सम्म प्रतीक्षा
    } else if (pid == 0) {
        // उप प्रक्रिया
        printf("Hello from child process!
");
    }
    return 0;
}

jōki no kōdo ma, fork kansū le ko purosesu banāuncha, ra oya purosesu wait kansū prayog garera ko purosesu ko shūryō ko pratikṣā garirahaeko cha.

रिटर्न मान ra hikisū

  • रिटर्न मान यदि उपप्रक्रिया समाप्त हुन्छ भने, त्यस प्रक्रियाको ID फिर्ता गर्दछ। यदि त्रुटि हुन्छ भने, …-1वापसी गर्दछु。
  • आर्गुमेन्ट तर्कको रूपमाint* statusयसलाई पास गरेर, उपप्रक्रियाको समाप्ति स्थिति प्राप्त गर्न सकिन्छ।
年収訴求

3. waitफङ्क्शनको आधारभूत प्रयोग

सरल कोड उदाहरण

waitफङ्क्शनको आधारभूत प्रयोगलाई तल देखाइन्छ।

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main() {
    pid_t pid = fork();
    if (pid > 0) {
        int status;
        wait(&status); // उपप्रक्रिया समाप्ति स्थिति प्राप्त गर्नुहोस्
        if (WIFEXITED(status)) {
            printf("Child exited with status: %d\n", WEXITSTATUS(status));
        }
    } else if (pid == 0) {
        printf("Child process running...\n");
        _exit(0); // उपप्रक्रिया समाप्ति
    }
    return 0;
}

नमूना कोडको व्याख्या

  1. wait(&status)सबप्रोसेसको समाप्तिको प्रतिक्षा गर्दछु।
  2. WIFEXITED(status)लाई प्रयोग गरेर, उपप्रक्रिया सामान्य रूपमा समाप्त भएको छ कि छैन जाँच गरिन्छ।
  3. WEXITSTATUS(status)हामी बच्चा प्रक्रियाको समाप्ति कोड प्राप्त गर्छौं।

यसरी、waitफङ्क्शन प्रयोग गरेर, अभिभावक प्रक्रिया सन्तान प्रक्रियाको समाप्ति स्थितिलाई ठीकसँग बुझ्न सक्छ।

4. जम्बी प्रक्रिया रwait फलनको सम्बन्ध

जम्बी प्रक्रिया भनेको

जम्बी प्रक्रिया भनेको, सन्तान प्रक्रिया समाप्त भएपछि, अभिभावक प्रक्रिया त्यसको समाप्ति स्थितिलाई उचित रूपमा सङ्कलन नगरेको खण्डमा उत्पन्न हुने प्रक्रिया हो। यस अवस्थामा, सन्तान प्रक्रिया आफै समाप्त भएको भए पनि, प्रक्रियाको जानकारी प्रणालीमा बाँकी रहन्छ।

यदि प्रणालीभित्र धेरै जम्बी प्रक्रियाहरू उपस्थित छन् भने, प्रक्रिया तालिकामा दबाब पर्न सक्छ, र अन्य प्रक्रियाहरू सामान्य रूपमा काम गर्न नसक्ने सम्भावना हुन्छ।

जम्बी प्रक्रियाको उत्पत्ति उदाहरण

तल जम्बी प्रक्रिया उत्पन्न हुने सरल उदाहरण हो।

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main() {
    pid_t pid = fork();
    if (pid > 0) {
        // मूल प्रक्रिया केही गर्दैन र प्रतिक्षा गर्दछ
        sleep(10);
    } else if (pid == 0) {
        // सन्तान प्रक्रिया
        printf("Child process exiting...
");
        _exit(0);
    }
    return 0;
}

यस उदाहरणमा, अभिभावक प्रक्रिया सन्तान प्रक्रियाको समाप्ति स्थितिलाई सङ्कलन नगरेको कारण, सन्तान प्रक्रिया समाप्तिपछि जम्बी स्थितिमा रहन्छ।

wait फलनद्वारा जम्बी प्रक्रियाको रोकथाम

wait फलन प्रयोग गरेर, अभिभावक प्रक्रिया सन्तान प्रक्रियाको समाप्ति स्थितिलाई उचित रूपमा सङ्कलन गर्न सक्छ, जसले जम्बी प्रक्रिया रोक्न मद्दत गर्छ।

तल यसको सुधारिएको संस्करणको उदाहरण हो।

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main() {
    pid_t pid = fork();
    if (pid > 0) {
        // मूल प्रक्रिया
        wait(NULL); // सन्तान प्रक्रियाको समाप्तिको प्रतिक्षा गरेर जिव्हा प्रक्रियालाई रोक्ने
        printf("मूल प्रक्रिया: सन्तान प्रक्रियालाई पुनः प्राप्त गरियो.\n");
    } else if (pid == 0) {
        // सन्तान प्रक्रिया
        printf("सन्तान प्रक्रिया बाहिर निस्किरहेछ...\n");
        _exit(0);
    }
    return 0;
}

यस कार्यक्रममा, wait(NULL) प्रयोग गरेर, अभिभावक प्रक्रिया सन्तान प्रक्रियाको समाप्तिको प्रतीक्षा गर्छ, जसले जम्बी प्रक्रियाको उत्पत्ति रोक्छ।

जम्बी प्रक्रिया उपायका बुँदाहरू

  1. निश्चित रूपमाwaitवाwaitpidउपयोग गर्नु
    उपप्रक्रियाहरूको अन्त्य स्थिति उपयुक्त रूपमा सङ्कलन गरेर, जॉम्बी प्रक्रियाहरूलाई रोक्न सकिन्छ।
  2. सिग्नल ह्यान्डलर प्रयोग गर्ने तरिका
    SIGCHLDसिग्नललाई पकड्ने र उपप्रोसेस समाप्त हुँदा स्वचालित रूपमा पुनःप्राप्त गर्ने तरिका छ।

तल यसको उदाहरण हो।

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
void sigchld_handler(int signo) {
    while (waitpid(-1, NULL, WNOHANG) > 0); // समाप्त भएका सबै बाल प्रक्रियाहरूलाई सङ्कलन गर्नुहोस्
}
int main() {
    signal(SIGCHLD, sigchld_handler); // SIGCHLD लाई ह्यान्डलरमा सेट गर्नुहोस्
    pid_t pid = fork();
    if (pid == 0) {
        // बाल प्रक्रिया
        printf("बाल प्रक्रिया बाहिर निस्किरहेछ...
");
        _exit(0);
    } else if (pid > 0) {
        // माता-पिता प्रक्रिया
        printf("माता-पिता प्रक्रिया अन्य काम गर्दैछ...
");
        sleep(10); // अन्य कार्यहरू चलिरहेको बेला SIGCHLD ह्यान्डलर सक्रिय हुन्छ
    }
    return 0;
}

यस विधिमा, अभिभावक प्रक्रिया स्पष्ट रूपमा wait कल नगरे पनि, समाप्त सन्तान प्रक्रिया स्वचालित रूपमा सङ्कलन हुन्छ।

5. waitpid सँगको भिन्नता

waitpid function भनेको के हो?

waitpid function ले, wait function जस्तै, सन्तान प्रक्रिया (child process) को समाप्ति पर्खनको लागि सिस्टम कल हो, तर यसले अझ लचिलो प्रक्रिया व्यवस्थापन सम्भव बनाउँछ। waitpid प्रयोग गरेर, विशेष सन्तान प्रक्रियालाई निर्दिष्ट गर्न वा नन-ब्लकिङ मोडमा पर्खन सकिन्छ।

मूलभूत प्रयोग र वाक्यरचना

waitpid function को वाक्यरचना तलको जस्तै छ।

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
pid_t waitpid(pid_t pid, int *status, int options);
  • pid प्रतीक्षा गर्ने चाइल्ड प्रोसेसको ID निर्दिष्ट गर्नुहोस्। निम्न विशेष मानहरू प्रयोग गरेर व्यवहार नियन्त्रण गर्न सकिन्छ।
  • pid > 0: विशिष्ट प्रोसेसको ID निर्दिष्ट गरेर प्रतीक्षा गर्नुहोस्।
  • pid == 0: पेरेंट प्रोसेसको समान प्रोसेस समूहमा रहेको कुनै पनि चाइल्ड प्रोसेसको प्रतिक्षा गर्नुहोस्।
  • pid < -1: निर्दिष्ट प्रक्रिया समूहको सबै प्रक्रियाहरूको प्रतिक्षा गर्नुहोस्।
  • pid == -1: कुनै पनि बाल प्रक्रिया प्रतीक्षा गर्नुहोस्waitफंक्शन जस्तै)
  • status सबप्रोसेसको अन्त्य स्थिति भण्डारण गर्ने पोइन्टर।
  • options क्रिया परिवर्तन गर्ने विकल्प निर्दिष्ट गर्नुहोस्। मुख्य मानहरू तल दिइएको छन्।
  • WNOHANG: नॉन‑ब्लकिङ मोड। समाप्त भएको चाइल्ड प्रोसेस नभएमा तुरुन्तै फिर्ता हुन्छ।
  • WUNTRACED: रोकिएको अवस्थाको चाइल्ड प्रोसेसहरूलाई पनि लक्ष्यमा समावेश गरिन्छ।
  • रिटर्न मान
  • सामान्य रूपमा समाप्त भएमा:समाप्त भएको चाइल्ड प्रोसेसको PID。
  • यदि उपप्रक्रिया छैन भने:0WNOHANGयदि निर्दिष्ट गरिएको छ भने)
  • त्रुटिको अवस्थामा:-1

waitpid function को उदाहरण

तलको उदाहरणमा, waitpid function प्रयोग गरेर विशेष सन्तान प्रक्रियालाई पर्खने उदाहरण देखाइएको छ।

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main() {
    pid_t pid1 = fork();
    if (pid1 == 0) {
        // उपप्रक्रिया १
        printf("उपप्रक्रिया १ चल्दैछ...
");
        sleep(2);
        _exit(1);
    }
    pid_t pid2 = fork();
    if (pid2 == 0) {
        // उपप्रक्रिया २
        printf("उपप्रक्रिया २ चल्दैछ...
");
        sleep(4);
        _exit(2);
    }
    int status;
    // विशिष्ट उपप्रक्रिया pid1 को प्रतिक्षा
    pid_t ret = waitpid(pid1, &status, 0);
    if (ret > 0 && WIFEXITED(status)) {
        printf("उपप्रक्रिया १ बाहिर निस्क्यो स्थिति: %d
", WEXITSTATUS(status));
    }
    // बाँकी उपप्रक्रिया को प्रतिक्षा
    waitpid(pid2, &status, 0);
    printf("उपप्रक्रिया २ बाहिर निस्क्यो स्थिति: %d
", WEXITSTATUS(status));
    return 0;
}

waitwaitpid को मुख्य भिन्नता

आइटमwaitwaitpid
प्रतीक्षा गर्ने लक्ष्यकुनै पनि बाल प्रक्रियाविशिष्ट उपप्रक्रिया निर्दिष्ट गर्न सकिन्छ
ब्लकिङसधैँ ब्लकिङनॉन‑ब्लकिङ सम्भव छ
विकल्प निर्दिष्टअसम्भवWNOHANG, WUNTRACED
लचिलोपनसीमितमहँगा

waitpid चयन गर्नु पर्ने अवस्थामा

  • यदि तपाईंले विशेष उपप्रक्रिया व्यवस्थापन गर्न चाहनुहुन्छ भने यो प्रोग्राममा धेरै उपप्रक्रिया बनाउने र प्रत्येकलाई अलग अलग नियन्त्रण गर्ने चाहना हुँदा उपयुक्त हुन्छ।
  • यदि तपाईं असिंक्रोनस प्रोसेसिङ गर्न चाहनुहुन्छ भने अन्य प्रक्रियाहरूलाई अवरोध नगरी प्रक्रियाको अन्त्य स्थिति जाँच गर्न चाहनुहुन्छ भने,WNOHANGविकल्प सुविधाजनक छ।

waitwaitpid को चयन मार्गदर्शन

  1. साधारण कार्यक्रमत्यसैले,waitफङ्सन पर्याप्त छ। यदि तपाईंले कुनै पनि सबप्रोसेसको प्रतिक्षा मात्र गर्नुहुन्छ भने, लचिलोपन आवश्यक छैन।
  2. जटिल प्रक्रिया व्यवस्थापनयदि … गर्नुहुन्छ भने,waitpidफङ्सनहरू सिफारिस गरिन्छ। विशेष गरी, जब असिन्क्रोनस प्रोसेसिङ वा विशिष्ट प्रक्रियाहरू नियन्त्रण गर्न आवश्यक हुन्छ,waitpidउपयोग गरेर, तपाईंले दक्षतापूर्वक व्यवस्थापन गर्न सक्नुहुन्छ।

6. बहु-थ्रेड वातावरणमा समक्रमण प्रक्रिया

प्रक्रिया समक्रमण र थ्रेड समक्रमणको भिन्नता

सी भाषामा, प्रक्रिया र थ्रेडहरू अलग प्रबंधन इकाईमा काम गर्छन्। प्रक्रिया समक्रमण(उदाहरण: waitwaitpid कार्यहरू) बहु प्रक्रिया बीचको समाप्ति अवस्था र स्रोत साझेदारीलाई नियन्त्रित गर्छ। अर्कोतर्फ, थ्रेड समक्रमणले एउटै प्रक्रियाभित्र थ्रेडहरू बीचको स्रोत व्यवस्थापन र क्रम नियमन गर्दछ।

बहु-थ्रेड वातावरणमा समक्रमण प्रक्रिया

थ्रेडहरू बीचको समक्रमण गर्दा सामान्यतया प्रयोग हुने चीजहरू सर्तीय चल र mutex हुन्। यहाँ, pthread लाइब्रेरीको सर्तीय चल प्रयोग गरेर समक्रमण विधि व्याख्या गरिन्छ।

सर्तीय चल प्रयोग गरेर समक्रमणको आधारभूत

सर्तीय चल(pthread_cond_t) प्रयोग गरेर, थ्रेडहरू बीचको पर्खाइ र सूचना प्रभावकारी रूपमा गर्न सकिन्छ।

सर्तीय चलका आधारभूत कार्यहरू

  • pthread_cond_wait शर्त पूरा नभएसम्म प्रतीक्षा गर्नुहोस्। प्रतीक्षाका क्रममा म्युटेक्सलाई मुक्त गर्नुहोस्।
  • pthread_cond_signal एक प्रतीक्षामा रहेको थ्रेडलाई उठाउँछौं।
  • pthread_cond_broadcast प्रतीक्षामा रहेका सबै थ्रेडहरूलाई जागृत गरिन्छ।

सर्तीय चल प्रयोग गरेर समक्रमणको उदाहरण

तल, सर्तीय चल प्रयोग गरेर बहु थ्रेडहरू बीचको समक्रमण गर्ने सरल उदाहरण छ।

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
// म्युटेक्स र कन्डिशन भेरिएबलको प्रारम्भ
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int shared_data = 0;
void* producer(void* arg) {
    pthread_mutex_lock(&mutex);
    printf("Producer: producing data...
");
    shared_data = 1;
    // कन्डिशन भेरिएबलमार्फत सूचना
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    return NULL;
}
void* consumer(void* arg) {
    pthread_mutex_lock(&mutex);
    // शर्त पूरा हुनेसम्म प्रतीक्षा
    while (shared_data == 0) {
        printf("Consumer: waiting for data...
");
        pthread_cond_wait(&cond, &mutex);
    }
    printf("Consumer: consumed data!
");
    pthread_mutex_unlock(&mutex);
    return NULL;
}
int main() {
    pthread_t producer_thread, consumer_thread;
    // थ्रेड सिर्जना
    pthread_create(&consumer_thread, NULL, consumer, NULL);
    sleep(1); // कन्ज्युमरलाई पहिले प्रतीक्षा गराउन स्लीप
    pthread_create(&producer_thread, NULL, producer, NULL);
    // थ्रेडको समाप्तिको प्रतीक्षा
    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);
    return 0;
}

नमूना कोडको व्याख्या

  1. म्युटेक्सको प्रयोग
    pthread_mutex_lockpthread_mutex_unlockलाई प्रयोग गरेर, साझा स्रोतहरूमा अनन्य पहुँच नियन्त्रण गरिन्छ।
  2. शर्त परिवर्तनशीलमा प्रतीक्षा र सूचना
  • कन्ज्युमर थ्रेड हो,pthread_cond_waitatshared_dataम यसलाई अपडेट हुने सम्म पर्खन्छु।
  • प्रोड्युसर थ्रेड हो,pthread_cond_signalकन्ज्युमर थ्रेडलाई सूचित गर्दछ।
  1. थ्रेडहरू बीचको सहकार्य
    उत्पादकले डेटा सिर्जना गर्छ, र उपभोक्ताले त्यसलाई प्राप्त गर्छ, सरल प्रवाहलाई साकार गर्दै।

थ्रेड समक्रमणमा ध्यान दिनुपर्ने बुँदाहरू

  • डेडलॉक रोकथाम म्युटेक्सको लॉक र अनलॉकको क्रममा ध्यान दिनु आवश्यक छ।
  • रिस्क कंडीशनबाट बच्ने थ्रेडहरू एकै समयमा शर्त परिवर्तन गर्ने प्रयास गर्दा, शर्त भेरिएबल र म्युटेक्सलाई सही तरिकाले संयोजन गर्न आवश्यक हुन्छ।
  • स्केलेबिलिटीको विचार एकाधिक थ्रेडहरू बीचमा दक्षतापूर्वक समक्रमण गर्न, अनावश्यक प्रतीक्षा र तालाबन्दीलाई न्यूनतम राख्नु महत्त्वपूर्ण छ।

बहु-थ्रेड वातावरणमा wait कार्यको प्रयोग सम्बन्धी ध्यान

wait कार्य प्रक्रिया बीचको समक्रमणका लागि हो, थ्रेड स्तरको समक्रमणका लागि उपयुक्त छैन। थ्रेडहरू बीचको समक्रमणमा, सर्तीय चल वा mutex प्रयोग गर्नु सुरक्षित र प्रभावकारी हुन्छ।

7. समस्या समाधान र उत्तम अभ्यासहरू

सामान्य त्रुटिहरू र समाधानहरू

C भाषा मा waitwaitpid प्रयोग गर्दा, केही सामान्य त्रुटिहरू देखा पर्न सक्छ। ती त्रुटिहरूको कारण र समाधानलाई व्याख्या गर्छौं।

1. wait कार्यले त्रुटि फिर्ता गर्छ

कारण

  • यदि सन्तान प्रक्रिया अस्तित्वमा छैन भने।
  • यदि सिस्टम कल अवरुद्ध भयो भने (EINTRत्रुटि)।

समाधान

  • उपप्रक्रिया अस्तित्वमा छ कि छैन जाँच गर्नुहोस्।
  • यदि सिस्टम कल अवरुद्ध हुन्छ भने, लूपमा पुनः प्रयास गर्नुहोस्।
int status;
while (wait(&status) == -1) {
    if (errno != EINTR) {
        perror("wait failed");
        break;
    }
}

2. Zombie प्रक्रिया उत्पन्न हुन्छ

कारण

  • मूल प्रक्रिया ले बच्चा प्रक्रियाको समाप्ति सङ्कलन गरेको छैन।

समाधान

  • मूल प्रक्रियामाwaitवाwaitpidउपयुक्त रूपमा प्रयोग गर्नुहोस्।
  • सिग्नल ह्यान्डलर सेट गरेर स्वतः समाप्ति सङ्कलन गर्ने।

3. स्पर्धात्मक शर्तहरू कारण अस्थिर व्यवहार

कारण

  • अनेक मूल प्रक्रियाहरू एउटै बाल प्रक्रियाको प्रतिक्षा गर्ने प्रयास गर्दा।
  • सन्तान प्रक्रियाको अन्त्य स्थिति सही रूपमा सङ्कलन गरिँदैन।

समाधान

  • प्रक्रिया ID स्पष्ट रूपमा निर्दिष्ट गर्दाwaitpidउपयोग गर्नुहोस्।
  • अनेक मूल प्रक्रियाहरूले एउटै बाल प्रक्रिया व्यवस्थापन नगर्ने गरी डिजाइन गर्नुहोस्।

उत्तम अभ्यासहरू

1. waitwaitpid को उचित चयन

  • साधारण प्रोग्राममाwaitपर्याप्त छ。
  • जटिल प्रक्रिया व्यवस्थापन (विशिष्ट उपप्रक्रिया नियन्त्रण वा असिंक्रोनस प्रक्रिया) आवश्यक परेमाwaitpidउपयोग गर्नुहोस्।

2. सिग्नल ह्यान्डलरको उपयोग

सिग्नल ह्यान्डलर प्रयोग गर्दा, अभिभावक प्रक्रिया स्पष्ट रूपमा wait कल नगरे पनि, सन्तान प्रक्रियाको समाप्ति स्थिति स्वचालित रूपमा सङ्कलन गर्न सक्छ। यसले Zombie प्रक्रिया रोक्दै, अभिभावक प्रक्रियाको कोडलाई संक्षिप्त राख्न मद्दत गर्छ।

3. त्रुटि प्रक्रियाको पूर्णता

waitwaitpid प्रणाली कलहरू हुन्, त्यसैले त्रुटि हुन सक्छ। सबै कलहरूको रिटर्न मान जाँच गरी, उचित रूपमा प्रक्रिया गरौं।

pid_t pid = wait(NULL);
if (pid == -1) {
    perror("wait error");
}

4. असिंक्रोनस प्रक्रियाको कार्यान्वयन

असिंक्रोनस प्रक्रिया गर्न चाहनुहुन्छ भने, तलको जस्तो डिजाइन सिफारिस गरिन्छ।

  • मुख्य प्रक्रियालाई अवरोध नगरी, नियमित रूपमाwaitpidलाईWNOHANGको साथमा कल गर्नुहोस्।
  • उपप्रक्रियाको समाप्ति स्थिति पोल गरेर, आवश्यक परेमा सङ्कलन गर्ने।

उदाहरण:

int status;
pid_t pid;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
    printf("Child process %d terminated.
", pid);
}

5. प्रक्रियाको संख्याको व्यवस्थापन

धेरै सन्तान प्रक्रियाहरू उत्पन्न गर्ने प्रोग्राममा, प्रक्रियाको संख्या नियन्त्रण गर्न आवश्यक हुन्छ।

  • एकै समयमा सिर्जना गरिने चाइल्ड प्रोसेसको संख्या सीमित गर्नुहोस्।
  • उपप्रक्रिया समाप्त हुने सम्म नयाँ प्रक्रिया सिर्जना नगर्ने डिजाइन अपनाउने।

8. बारम्बार सोधिने प्रश्न(FAQ)

Q1: waitकार्यलाई प्रयोग नगरी zombie प्रक्रिया रोक्ने तरिका के हो?

A:
waitकार्यलाई प्रयोग नगरी पनि, सिग्नल ह्यान्डलर प्रयोग गरेर zombie प्रक्रिया रोक्न सकिन्छ। अभिभावक प्रक्रिया SIGCHLD सिग्नललाई पक्रेर, सन्तान प्रक्रियाको समाप्ति स्थितिलाई स्वचालित रूपमा सङ्कलन गर्छ।

तल सिग्नल ह्यान्डलर प्रयोग गरेको उदाहरण हो।

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
void handle_sigchld(int sig) {
    while (waitpid(-1, NULL, WNOHANG) > 0);
}
int main() {
    signal(SIGCHLD, handle_sigchld);
    if (fork() == 0) {
        // बच्चा प्रक्रिया
        _exit(0);
    }
    // मूल प्रक्रिया को कार्य
    sleep(5);
    printf("Parent process completed.\n");
    return 0;
}

Q2: waitpidलाई प्रयोग गर्नु उपयुक्त हुने परिस्थितिहरू के हुन्?

A:
waitpid तलका जस्ता अवस्थामा उपयुक्त हुन्छ।

  • विशिष्ट उपप्रक्रिया मात्रको प्रतिक्षा गर्न चाहनुहुन्छ भने (pidलाई निर्दिष्ट गर्नुहोस्)。
  • प्रोसेसलाई असिंक्रोनस रूपमा व्यवस्थापन गर्न चाहनुहुन्छ भने (WNOHANGविकल्प प्रयोग गर्नुहोस्)।
  • यदि तपाईं रोकिएको उपप्रक्रिया जाँच गर्न चाहनुहुन्छ भने(WUNTRACEDविकल्प प्रयोग गर्नुहोस्)।

Q3: waitकार्यले मान फिर्ता नदिएमा कारण के हो?

A:
waitकार्यले मान फिर्ता नदिने(-1 फिर्ता गर्ने)कारणहरू तलका अनुसार हुन सक्छन्।

  1. उपप्रक्रिया अस्तित्वमा छैन।
  • प्रक्रिया पहिले नै समाप्त भइसकेको छ, अथवाforkयो असफल हुन सक्छ।
  1. सिस्टम कल अवरुद्ध भयो (EINTRत्रुटि)।
  • सिग्नलको कारणले भएको अवरोध भएमा, लूपमा पुनः प्रयास गर्नुहोस्।
int status;
pid_t pid;
while ((pid = wait(&status)) == -1) {
    if (errno != EINTR) {
        perror("wait error");
        break;
    }
}

Q4: मल्टिथ्रेड प्रोग्राममा waitकार्यलाई सुरक्षित रूपमा प्रयोग गर्ने तरिका के हो?

A:
मल्टिथ्रेड प्रोग्राममा wait प्रयोग गर्दा, तलका बुँदाहरूमा ध्यान दिनुहोस्।

  • waitयो प्रक्रिया स्तरमा काम गर्दछ, त्यसैले थ्रेड स्तरमा समक्रमणको लागि कन्डिसन भेरिएबल र म्युटेक्स प्रयोग गर्नुहोस्।
  • सन्तान प्रक्रियाको व्यवस्थापन सामान्यतया मुख्य थ्रेडमा सीमित गर्नु सुरक्षित हुन्छ। अन्य थ्रेडहरू…waitलाई कल गर्दा अनपेक्षित व्यवहार उत्पन्न हुन सक्छ。

Q5: waitकार्यको वैकल्पिक उपायहरू छन्?

A:
तलका वैकल्पिक उपायहरू उपलब्ध छन्।

  • waitpidकार्य उच्च लचिलोपन छ, र विशिष्ट प्रक्रियाहरूलाई नियन्त्रण गर्न सकिन्छ।
  • सिग्नल ह्यान्डलर उपप्रक्रियाहरूको समाप्ति असिंक्रोनस रूपमा प्रक्रिया गरिन्छ।
  • इभेन्ट-आधारित प्रोग्रामिङ इभेन्ट लूप (उदाहरण: selectआणिpoll)लाई प्रयोग गरेर प्रोसेस समाप्ति व्यवस्थापन गर्ने तरिका पनि छ।

Q6: सन्तान प्रक्रिया समाप्त नहुनुमा के गर्ने?

A:
सन्तान प्रक्रिया रोकिएको हुन सक्छ। यस अवस्थामा, तलका चरणहरूमा समाधान गर्नुहोस्।

  1. WUNTRACEDविकल्प प्रयोग गरेर रोकेका सबप्रोसेसहरू जाँच गर्नुहोस्।
  2. आवश्यकता अनुसार,killसिस्टम कल प्रयोग गरेर सबप्रोसेस समाप्त गरिन्छ।

Q7: waitकार्यले प्राप्त गर्न सक्ने समाप्ति स्थितिको अर्थ के हो?

A:
wait कार्यले प्राप्त गरेको status मा तलका जानकारीहरू समावेश छन्।

  • सामान्य समाप्ति: WIFEXITED(status)सत्य फर्काउँछ, र अन्त्य कोड होWEXITSTATUS(status)द्वारा प्राप्त गर्न सकिन्छ।
  • असामान्य समाप्ति: यदि सिग्नल द्वारा समाप्त भयो भनेWIFSIGNALED(status)सत्य फर्काउँछ, र अन्त्य सिग्नल होWTERMSIG(status)द्वारा प्राप्त गर्न सकिन्छ।

例:

int status;
wait(&status);
if (WIFEXITED(status)) {
    printf("Exited with code: %d
", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
    printf("Killed by signal: %d
", WTERMSIG(status));
}

Q8: धेरै सन्तान प्रक्रियाहरूलाई एकै साथ व्यवस्थापन गर्ने तरिका के हो?

A:
धेरै सन्तान प्रक्रियाहरूलाई व्यवस्थापन गर्दा、waitpid लाई लूपमा प्रयोग गरेर सबै प्रक्रियाहरूलाई सङ्कलन गर्ने विधि सामान्य हो।

9. सारांश

यस लेखमा, C भाषा को wait कार्यलाई केन्द्रित गरी, आधारभूत प्रयोगबाट अनुप्रयोग उदाहरण, सम्बन्धित विषयहरू (waitpid कार्य र जम्बी प्रक्रिया समाधान) सम्मलाई व्यापक रूपमा व्याख्या गरिएको छ। तल महत्वपूर्ण बुँदाहरूको सारांश प्रस्तुत गरिएको छ।

wait कार्यको आधारभूत

  • waitयो फङ्सन एक सिस्टम कल हो जसले मूल प्रक्रिया (parent process) लाई बच्चा प्रक्रियाको समाप्तिको प्रतिक्षा गर्न र त्यसको समाप्ति स्थिति सङ्कलन गर्न अनुमति दिन्छ।
  • wait(NULL)यसलाई प्रयोग गरेर, समाप्ति स्थिति जाँच नगरी सजिलै उपप्रक्रिया को प्रतिक्षा गर्न सक्नुहुन्छ।

अनुप्रयोग र सम्बन्धित विषयहरू

  • जम्बी प्रोसेसको प्रतिकार यदि तपाईंले बाल प्रक्रियाको अन्त्य स्थिति सङ्कलन नगर्नुहुन्छ भने, जॉम्बी प्रक्रिया उत्पन्न हुन्छ।waitwaitpidउपयुक्त रूपमा प्रयोग गरेर यसलाई रोक्न सकिन्छ।
  • waitpidकार्य विशिष्ट उपप्रक्रिया निर्दिष्ट गरेर प्रतीक्षा गर्न, वा असिंक्रोनस प्रक्रिया गर्न चाहनुहुन्छ भने यो अत्यन्त उपयोगी छ।
  • सिग्नल ह्यान्डलरSIGCHLDसिग्नल प्रयोग गर्दा, अभिभावक प्रक्रिया स्पष्ट रूपमाwaitयसलाई कल नगरेको भए पनि, अन्त्य अवस्थालाई स्वचालित रूपमा पुनःप्राप्त गर्न सकिन्छ।

बहु-थ्रेड वातावरणमा ध्यान दिनु पर्ने कुरा

  • waitफङ्सनले प्रक्रियाहरू बीचको समन्वय गर्दछ, तर थ्रेड-स्तरको समन्वयको लागि कन्डिसन भेरिएबल र म्युटेक्स प्रयोग गर्नु उपयुक्त हुन्छ।
  • एकै समयमा धेरै थ्रेडहरूwaitकुनै पनि कल नगर्ने गरी डिजाइन गर्नु महत्त्वपूर्ण छ।

समस्या समाधान र उत्तम अभ्यासहरू

  • waitआणिwaitpidरिटर्न मानलाई निश्चित रूपमा जाँच गर्नुहोस्, र त्रुटि प्रक्रियालाई उपयुक्त रूपमा अंमलमा ल्याऔं।
  • यदि असिंक्रोनस प्रोसेसिङ आवश्यक छ भने,WNOHANGविकल्पहरूलाई उपयोग गरेर कुशल प्रक्रिया व्यवस्थापन सम्भव छ।
  • साधारण डिजाइनलाई मनमा राखेर अनावश्यक प्रक्रिया सिर्जना र जटिल निर्भरता टाढा राख्ने प्रयास गरौँ।

अगाडि सिक्नुपर्ने कुरा

wait कार्य र प्रक्रिया समक्रमणको आधारभूत बुझिसकेपछि, अर्को चरणको रूपमा तलका विषयहरू सिक्न सिफारिस गरिन्छ:

  • प्रोसेसहरू बीच संचार (IPC) पाइप, सन्देश कतार, साझा स्मृति प्रयोग गरेर डेटा आदान‑प्रदान गर्ने तरिका।
  • असिंक्रोनस प्रोग्रामिङ इभेन्ट-आधारित प्रोग्रामिङ वा असिंक्रोनस I/O को उपयोग गर्ने तरिका।
  • forkफङ्सन र प्रक्रिया सिर्जनाका विवरण सन्तान प्रक्रियाको सिर्जनामा स्मृति व्यवस्थापन र प्रक्रियाको विभाजनको व्यवहार।

यस लेख मार्फत, C भाषा को wait कार्य र यसको सम्बन्धित ज्ञानलाई गहिरो रूपमा बुझ्नुभएको आशा गर्दछौं। उपयुक्त प्रक्रिया व्यवस्थापनलाई कार्यान्वयन गरेर, प्रभावकारी र स्थिर प्रोग्राम विकासमा सहयोगी बन्ने आशा गर्दछौं।

年収訴求