Panggilan sistem _exit(), fork() dan waitpid()

Jadi, saya keluar dari utas anak kembali ke induk. Saya menggunakan panggilan sistem _exit(). Saya bertanya-tanya beberapa hal. Salah satunya adalah parameter _exit untuk anak saya. Berikut adalah kode yang dijalankan oleh proses anak saya:

printf("\n****Child process.****\n\nSquence: ");

 do{
        //Print the integer in the sequence.
        printf("%d\t",inputInteger);
        if((inputInteger%2) == 0){
            //printf("inputInteger = %d\n", inputInteger);
            inputInteger = inputInteger / 2;
        }else{
            inputInteger = 3*inputInteger +1;
            //printf("%d\t",inputInteger);
        }

    }while(inputInteger != 1);

    //Makes sure we print off 1!
    printf("%d\n\n", inputInteger);

    //Properly exit
    _exit(status);

Saya menggunakan status karena di thread induk saya, saya menggunakannya dalam panggilan sistem waitpid(). Berikut adalah kode untuk proses induk yang dijalankan setelah anak selesai.

waitpid_check = waitpid(processID, &status, 0);
        printf("\n****Parent process.****\n");

        if(waitpid_check == -1){
            printf("Error in waitpid.\n");
            exit(EXIT_FAILURE);
        }

        if(WIFEXITED(status)){
            printf("Child process terminated normally!\n");
        }

Di sini saya menggunakan panggilan sistem waitpid() yang memastikan bahwa anak tersebut keluar, kemudian menggunakan status untuk memeriksa apakah sudah keluar dengan benar. Saya bertanya-tanya apakah saya melakukan hal ini dengan cara yang benar dalam menciptakan dan mengeluarkan anak.

Lalu saya juga bertanya-tanya apakah saya sudah memeriksa dengan benar keluarnya anak di induknya.

Terima kasih atas bantuan Anda!


person pmac89    schedule 18.02.2014    source sumber
comment
Apakah kita membicarakan thread atau proses di sini? Dari panggilan tersebut, sepertinya Anda berurusan dengan proses anak, bukan thread anak.   -  person jia103    schedule 18.02.2014
comment
Ya, saya berurusan dengan proses.   -  person pmac89    schedule 18.02.2014


Jawaban (2)


Dari manual waitpid linux.

"Jika status bukan NULL, wait() dan waitpid() menyimpan informasi status dalam int yang ditunjuknya."

Anda tidak memerlukan nilai pengembalian dari waitpaid untuk memeriksa apakah turunan tersebut gagal. Anda perlu memeriksa nilai status. Ada beberapa makro untuk memeriksa status.

WIFEXITED(status)
returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().
WEXITSTATUS(status)
returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a return statement in main(). This macro should only be employed if WIFEXITED returned true.
WIFSIGNALED(status)
returns true if the child process was terminated by a signal.
WTERMSIG(status)
returns the number of the signal that caused the child process to terminate. This macro should only be employed if WIFSIGNALED returned true.
WCOREDUMP(status)
returns true if the child produced a core dump. This macro should only be employed if WIFSIGNALED returned true. This macro is not specified in POSIX.1-2001 and is not available on some UNIX implementations (e.g., AIX, SunOS). Only use this enclosed in #ifdef WCOREDUMP ... #endif.
WIFSTOPPED(status)
returns true if the child process was stopped by delivery of a signal; this is only possible if the call was done using WUNTRACED or when the child is being traced (see ptrace(2)).
WSTOPSIG(status)
returns the number of the signal which caused the child to stop. This macro should only be employed if WIFSTOPPED returned true.
WIFCONTINUED(status)
(since Linux 2.6.10) returns true if the child process was resumed by delivery of SIGCONT.

Adapun apakah Anda keluar dari proses anak dengan benar atau tidak, itu sangat tergantung. Anda akan keluar seperti yang Anda lakukan di program lain karena ketika Anda melakukan fork suatu proses, Anda sebenarnya hanya menduplikasi ruang alamat dan anak ketika dijalankan sebagai program independennya (tentu saja dengan FD terbuka yang sama, nilai yang sudah dideklarasikan, dll sebagai induk) . Di bawah ini adalah implementasi umum untuk masalah ini (walaupun NULL diteruskan ke menunggu alih-alih status, jadi menurut saya Anda melakukannya dengan benar.)

/* fork a child process */
pid = fork();

if (pid < 0) { /* error occurred */
    fprintf(stderr, "Fork Failed\n");
    return 1;
}
else if (pid == 0) { /* child process */
    printf("I am the child %d\n",pid);
    execlp("/bin/ls","ls",NULL);
}
else { /* parent process */
    /* parent will wait for the child to complete */
    printf("I am the parent %d\n",pid);
    wait(NULL);

    printf("Child Complete\n");
}

return 0;
person PandaRaid    schedule 18.02.2014
comment
Terima kasih, saya melewatkan bagian _exit(2) di halaman manual. Itu adalah pertanyaan utama saya. Saya hanya tidak ingin menampilkan semua kode saya karena ini adalah tugas. - person pmac89; 19.02.2014

Saya ingin membantu tetapi saya sangat kesulitan dalam menerima panggilan ini. Jika Anda telah membaca dokumentasi tentang panggilan API ini dan memeriksa di mana-mana apakah ada pengembalian kesalahan, Anda seharusnya berada dalam kondisi yang baik.

Idenya tampaknya bagus pada tingkat tinggi.

Satu hal yang perlu diingat adalah Anda mungkin ingin mengelilingi daging anak Anda dengan metode coba/tangkap. Dengan thread, Anda sering kali tidak ingin pengecualian mengacaukan alur utama Anda.

Anda tidak akan mengalami masalah dengan banyak proses, tetapi pikirkan apakah Anda ingin _exit dipanggil saat ada pengecualian, dan bagaimana mengomunikasikan (kepada induk atau pengguna) bahwa pengecualian terjadi.

person jia103    schedule 18.02.2014