انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


ارائه ۲۴٫۱۰ اوبونتو منتشر شد 🎉

نویسنده موضوع: c - خارج نشدن پروسه فرزند بعد از exit  (دفعات بازدید: 2676 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین B

  • Sr. Member
  • *
  • ارسال: 354
  • جنسیت : پسر
c - خارج نشدن پروسه فرزند بعد از exit
« : 04 اردیبهشت 1393، 05:42 ق‌ظ »
در کد زیر علی‌الظاهر باید هر ۵ ثانیه یه پروسه فرزند ایجاد بشه و بعد از چاپ پیغام توسط فرزند برنامه‌ی فرزند به اتمام برسه (توسط exit)

که هر ۵ ثانیه پروسه جدید ایجاد میشه و پیغام چاپ میشه
ولی مشکل اینه که پروسه‌ی فرزند همچنان بعد از exit شدن هم در سیستم باقی میمونه!! (توسط دستور ps‌ میشه آیدیش رو دبد)

ممنون میشم یه راهنمایی بفرمایید

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

int main(){
    int i;
    for(i=0;i<=300;i++){
        pid_t f;
        f=fork();
        if(f==0){
            //child
            fprintf (stderr, "[C1] %d\n",i);
            exit(0);
        }else if(f>0){
            usleep(5000000);
        }
    }
    return 0;
}
« آخرین ویرایش: 04 اردیبهشت 1393، 05:45 ق‌ظ توسط B »

آفلاین محسن صفری

  • Jr. Member
  • *
  • ارسال: 47
  • جنسیت : پسر
    • صفری آنلاین
پاسخ : c - خارج نشدن پروسه فرزند بعد از exit
« پاسخ #1 : 04 اردیبهشت 1393، 09:51 ق‌ظ »
نمونه خروجی ps من اینجوریه :

1541  0  Z+   0:00.00 <defunct
1546  0  Z+   0:00.00 <defunct

$ man ps | grep "dead process"        
Z       Marks a dead process (a ``zombie'').


Z یعنی Zombie process و   یعنی پروسسی که تموم شده ولی باباش هنوز اونو جمع آوری نکرده .
« آخرین ویرایش: 04 اردیبهشت 1393، 10:09 ق‌ظ توسط محسن صفری »

آفلاین B

  • Sr. Member
  • *
  • ارسال: 354
  • جنسیت : پسر
پاسخ : c - خارج نشدن پروسه فرزند بعد از exit
« پاسخ #2 : 04 اردیبهشت 1393، 12:39 ب‌ظ »
دست شما درد نکنه

باباش باید چطوری اونو جمع آوری کنه؟

آفلاین محسن صفری

  • Jr. Member
  • *
  • ارسال: 47
  • جنسیت : پسر
    • صفری آنلاین
پاسخ : c - خارج نشدن پروسه فرزند بعد از exit
« پاسخ #3 : 04 اردیبهشت 1393، 08:14 ب‌ظ »
توی مورد شما  تست کردم باباش تموم بشه اون ها هم جمع آوری می شن و از جدول process ها حذف می شن ولی برای موقعیت های دیگه اطلاعات کافی ندارم که اظهار نظر کنم .

ولی اگر بابا روی پروسس بچه wait کنه تا تموم بشه zoombie ایجاد نمی شه .

کد شما رو این جوری تغییر دادم :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

int main(){
    int i;
    for(i=0;i<=300;i++){
        pid_t f;
        f=fork();
        if(f==0){
            //child
    usleep(5000000);
            fprintf (stderr, "[C1] %d\n",i);
            exit(0);
        }else if(f>0){
wait();
        }
    }
    return 0;
}

پروسس بچه 5 ثانیه می خوابه و یه چیزی می نویسه و بعد خارج می شه . در تمام این مدت بابا منتظر تموم شدن بچه ش می مونه و بعد دوباره پروسس جدید ایجاد می کنه .


آفلاین B

  • Sr. Member
  • *
  • ارسال: 354
  • جنسیت : پسر
پاسخ : c - خارج نشدن پروسه فرزند بعد از exit
« پاسخ #4 : 05 اردیبهشت 1393، 12:46 ق‌ظ »
آخه مشکل اینجاست که میخوام در سوکت ازش استفاده کنم و پروسه والد نباید منتظر بمونه فرزندش تموم بشه!!
باید به سوکت گوش بده و اگه درخوواستی اومد اونو قبول کنه و باقی کار رو پروسه فرزندش به گردن بگیره

آفلاین محسن صفری

  • Jr. Member
  • *
  • ارسال: 47
  • جنسیت : پسر
    • صفری آنلاین
پاسخ : c - خارج نشدن پروسه فرزند بعد از exit
« پاسخ #5 : 05 اردیبهشت 1393، 11:16 ق‌ظ »
پروسس Zombie پروسس مرده هست و هیچ resource ای دستش نیست . اعمم از CPU و یا memory و چون مرده است با دستور kill کشته نمی شه .

به طور طبیعی بچه وقتی تموم می شه باباش باید بتونه exit status اونو بخونه . توی کد شما بچه به سرعت اجرا می شه و تموم می شه ولی باباش 5 ثانیه می خوابه . چون بچه تموم شده و باباش نتونسته exit status اونو بخونه Zombie می شه .

Zombie فقط یک مدخل توی جدول پروسس ها می گیره تا باباش  exit status اونو بخونه و شاید زیاد هم اذیت نکنه ولی اگر نباشه یقینا زیباتره .

برای اینکه این مورد رو تست کنید کد زیر رو ببینید .

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

int main(){
    int i;
int b = 0;
    for(i=0;i<=300;i++){
        pid_t f;
if (b >= 5) {
printf("b is %d\n", b);
b = 0;
wait();
wait();
wait();
wait();
wait();
}

b++;
        f=fork();
        if(f==0){
            //child
            fprintf (stderr, "[C1] %d\n",i);
            exit(0);
        }else if(f>0){
usleep(2000000);
kill(getpid(), SIGCHLD);
        }
    }
    return 0;
}

b یک شمارنده است که 5 بار که for اجرا شد 5 بار wait می کنه و 5 تا zombie از جدول پروسس ها حذف می شن .

به طور کلی به نظرم باید توی کدی که می نویسید از یک approach (رهیافت) دیگه استفاده کنید تا جلوی zoombie رو بگیرید .
« آخرین ویرایش: 05 اردیبهشت 1393، 11:27 ق‌ظ توسط محسن صفری »

آفلاین B

  • Sr. Member
  • *
  • ارسال: 354
  • جنسیت : پسر
پاسخ : c - خارج نشدن پروسه فرزند بعد از exit
« پاسخ #6 : 05 اردیبهشت 1393، 02:54 ب‌ظ »
دست شما درد نکنه

با این حساب با هر بار wait یه زامبی از بین میره؛ در نتیجه این کار رو کردم

اول یک هندل ثبت کردم که اگه فرزندی کارش تموم شد پروسه والد سیگنالش رو دریافت کنه و تابع s رو صدا بزنه
signal (SIGCHLD, s);
و بعد توی تابع s هم تابع wait رو صدا زدم ؛ که اینطوری به ازای هر فرزندی تموم میشه و میشه زامبی یدونه wait صدا زده میشه و زامبی حذف میشه (ورواقع اینطوری یه چیزی شبیه کدی که شما ایجاد کردید میشه)



** مشکل این روش اینه که وقتی از سیگنال استفاده میکنیم پروسه والد ریسیت میشه (که البته مهم هم نیست) **

دست شما درد نکنه آقا محسن

آفلاین B

  • Sr. Member
  • *
  • ارسال: 354
  • جنسیت : پسر
پاسخ : c - خارج نشدن پروسه فرزند بعد از exit
« پاسخ #7 : 05 اردیبهشت 1393، 03:01 ب‌ظ »
kill(getpid(), SIGCHLD);
اینو متوجه نشدم!
این دستور میاد به پروسه والد (به خودش) سیگنال میفرسته که فرزندش تموم شده؟! چرا اینکارو کردید؟
ممنون

آفلاین محسن صفری

  • Jr. Member
  • *
  • ارسال: 47
  • جنسیت : پسر
    • صفری آنلاین
پاسخ : c - خارج نشدن پروسه فرزند بعد از exit
« پاسخ #8 : 05 اردیبهشت 1393، 03:35 ب‌ظ »
kill(getpid(), SIGCHLD);
این خط رو فراموش کنید . روی کد شما که کار می کردم توی یکی از مراحل تست این خط رو اضافه کردم ولی کار نکرد و آخر سر باید حذفش می کردم ولی یادم رفت . عذر می خوام .

این ها رو از توی ویکی پدیا کپی کردم .
On Unix and Unix-like computer operating systems, a
 zombie process or defunct process is
 a process that has completed execution but still has an entry in the process table.
 This entry is still needed to allow the parent process to
 read its child's exit status.

و این یکی

To remove zombies from a system, the SIGCHLD signal can be sent to the parent
manually, using the kill command. If the parent process still refuses to reap
 the zombie, the next step would be to remove the parent process. When a process
loses its parent, init becomes its new parent. init periodically executes the
wait system call to reap any zombies with init as parent.To remove zombies from
a system, the SIGCHLD signal can be sent to the parent manually, using the
kill command. If the parent process still refuses to reap the zombie,
 the next step would be to remove the parent process. When a process
 loses its parent, init becomes its new parent. init
periodically executes the wait system call to reap any zombies with init as parent.

کل مطلب :

http://en.wikipedia.org/wiki/Zombie_process