The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Вызов fork и процессы"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Вызов fork и процессы"
Сообщение от Bushi Искать по авторуВ закладки on 03-Мрт-04, 09:02  (MSK)
Пишу биллинг (любимое заняти российский юниксоидов :). Программа переодически по rsh снимает статистику с маршрутизатора. Для этого главный процесс создает pipe, процесс форкается, затем стандартный поток вывода в дочернем процессе перенаправляется в pipe и с помощью вызова exec запускается утилита rsh, которая в стандартный поток вывода выдает информацию. Затем дочерний процесс естественно закрывается.
Но при вызове ps видно все дочерние процессы.
# ps -waux | grep cbir
cbir       0  0,0  0,0     0    0  ??  ZW   -         0:00,00  (rsh)
cbir       0  0,0  0,0     0    0  ??  ZW   -         0:00,00  (rsh)
cbir       0  0,0  0,0     0    0  ??  ZW   -         0:00,00  (rsh)
.................
cbir       0  0,0  0,0     0    0  ??  ZW   -         0:00,00  (rsh)
cbir       0  0,0  0,0     0    0  ??  ZW   -         0:00,00  (rsh)
cbir       0  0,0  0,0     0    0  ??  ZW   -         0:00,00  (rsh)
cbir   57939  0,0  0,2  2792 1372  ??  Is   10:27     0:00,00 /usr/local/sbin/cbir

в чем дело? Откуда эта информация? Ведь все дочерние процессы завершили свою работу?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Вызов fork и процессы"
Сообщение от vnp emailИскать по авторуВ закладки on 03-Мрт-04, 20:47  (MSK)
>Пишу биллинг (любимое заняти российский юниксоидов :). Программа переодически по rsh снимает
>статистику с маршрутизатора. Для этого главный процесс создает pipe, процесс форкается,
>затем стандартный поток вывода в дочернем процессе перенаправляется в pipe и
>с помощью вызова exec запускается утилита rsh, которая в стандартный поток
>вывода выдает информацию. Затем дочерний процесс естественно закрывается.
>Но при вызове ps видно все дочерние процессы.
># ps -waux | grep cbir
>cbir       0  0,0  0,0 0    0  ?? ZW   -  0:00,00  (rsh)
[...]
>в чем дело? Откуда эта информация? Ведь все дочерние процессы завершили свою
>работу?

Обратите внимание на флажки состояния Z и W. Если внимательно прочитать man ps, то можно узнать, что процесс стал зомби, и останется таковым, пока родитель не вызовет wait(). Борются с этим либо ловлей SIGCHLD, либо двойным форком.


  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Вызов fork и процессы"
Сообщение от Bushi Искать по авторуВ закладки on 04-Мрт-04, 08:48  (MSK)
>>Пишу биллинг (любимое заняти российский юниксоидов :). Программа переодически по rsh снимает
>>статистику с маршрутизатора. Для этого главный процесс создает pipe, процесс форкается,
>>затем стандартный поток вывода в дочернем процессе перенаправляется в pipe и
>>с помощью вызова exec запускается утилита rsh, которая в стандартный поток
>>вывода выдает информацию. Затем дочерний процесс естественно закрывается.
>>Но при вызове ps видно все дочерние процессы.
>># ps -waux | grep cbir
>>cbir       0  0,0  0,0 0    0  ?? ZW   -  0:00,00  (rsh)
>[...]
>>в чем дело? Откуда эта информация? Ведь все дочерние процессы завершили свою
>>работу?
>
>Обратите внимание на флажки состояния Z и W. Если внимательно прочитать man
>ps, то можно узнать, что процесс стал зомби, и останется таковым,
>пока родитель не вызовет wait(). Борются с этим либо ловлей SIGCHLD,
>либо двойным форком.


Спасибо за ответ! С помощью wait проблема решена. А что такое двойной форк? Можете объяснить?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "Вызов fork и процессы"
Сообщение от vnp emailИскать по авторуВ закладки on 04-Мрт-04, 10:32  (MSK)
>Спасибо за ответ! С помощью wait проблема решена. А что такое двойной
>форк? Можете объяснить?

Идея в следующем: Родитель должен ждать завершения потомка. Если родитель завершился первым, заботы о потомке берет на себя init. Если потомки порождаются и заканчиваются непредсказуемо и независимо друг от друга, бывает полезна такая модель:

if((pid = fork()) > 0) {
   waitpid(pid, ...);
} else {
    if(fork() > 0) {
        exit(0);
    } else {
        exec...
    }
}

В такой редакции "первый потомок" завершается немедленно, т.е. wait() не блокируется, и не надо заморачиваться с portability issues вокруг SIGCHLD.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "Вызов fork и процессы"
Сообщение от Bushi Искать по авторуВ закладки on 04-Мрт-04, 10:34  (MSK)
>Идея в следующем: Родитель должен ждать завершения потомка. Если родитель завершился первым,
>заботы о потомке берет на себя init. Если потомки порождаются и
>заканчиваются непредсказуемо и независимо друг от друга, бывает полезна такая модель:
>
>
>if((pid = fork()) > 0) {
>   waitpid(pid, ...);
>} else {
>    if(fork() > 0) {
>        exit(0);
>    } else {
>        exec...
>    }
>}
>
>В такой редакции "первый потомок" завершается немедленно, т.е. wait() не блокируется, и
>не надо заморачиваться с portability issues вокруг SIGCHLD.


Спасибо, идею понял.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "Вызов fork и процессы"
Сообщение от dmi emailИскать по авторуВ закладки on 29-Мрт-04, 18:01  (MSK)
Если следовать теории что после каждого раздвоения процесса надо ждать завершения процесса-потомка, то значит ли это что никакой многозадачности не может быть впринципе?
  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "Вызов fork и процессы"
Сообщение от Bushi Искать по авторуВ закладки(??) on 29-Мрт-04, 18:56  (MSK)
>Если следовать теории что после каждого раздвоения процесса надо ждать завершения процесса-потомка,
>то значит ли это что никакой многозадачности не может быть впринципе?
>


Нет, после раздвоения каждый процесс живет своей жизнью, только они находятся в одной группе и дочерний процесс, завершив свою работу, будет болтаться в памяти, став "зомби" (не потребляя при этом ресурсов процессора) до тех пор, пока родительский процесс не сделает wait либо не завершит свою работу.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "Вызов fork и процессы"
Сообщение от dmi emailИскать по авторуВ закладки on 29-Мрт-04, 19:19  (MSK)
Вот утрированный кусок из моего кода, если можно, скажите где ошибка - Вы спасете огромное кол-во моих нервных клеток и благада моя не будет знать границ :-). Заранее спасибо.

while (1)
    {

        int msg_sock=0;
        int cli_len=sizeof(cli_addr);
        msg_sock=accept(m_sock, (struct sockaddr*)&cli_addr, (socklen_t*)&cli_len);
        if (msg_sock<=0)
            ...

        pid_t pid;
        if ((pid=fork ())==0)
        {
                OnConnect connect;
                connect.Begin();
                close (msg_sock);
                _exit(0);
        } else
        {
            /*Kill zombie */
            while (waitpid(pid, NULL, WNOHANG) > 0);
            /*если тут сделать wait() то одновременно смогут работать только 1 юзер*/
        }
    }
    close (m_sock);

  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "Вызов fork и процессы"
Сообщение от vnp emailИскать по авторуВ закладки on 29-Мрт-04, 21:03  (MSK)
>Вот утрированный кусок из моего кода, если можно, скажите где ошибка -
>Вы спасете огромное кол-во моих нервных клеток и благада моя не
>будет знать границ :-). Заранее спасибо.
>
>while (1)
>    {
>        pid_t pid;
>        if ((pid=fork ())==0)
>        {
>    OnConnect connect;
>    connect.Begin();
>    close (msg_sock);
>    _exit(0);
>        } else
>        {
>            
>/*Kill zombie */
>            while (waitpid(pid, NULL, WNOHANG) > 0);
>            
>/*если тут сделать wait() то одновременно смогут работать только 1 юзер*/

В такой редакции, да, только один. Выше в треде были описаны две техники
(ловля SIGCHLD и double fork), позволяющие обойти проблему.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "Вызов fork и процессы"
Сообщение от dmi emailИскать по авторуВ закладки on 30-Мрт-04, 10:46  (MSK)
Если я правильно понял - то надо сделать было так, только зомбики всеравно растут :-(
while (1)
    {
        int msg_sock=0;
        int cli_len=sizeof(cli_addr);
        msg_sock=accept(m_sock, (struct sockaddr*)&cli_addr, (socklen_t*)&cli_len);
        if (msg_sock<=0)
            ...

        pid_t pid;
        if((pid = fork()) > 0)
        {
            waitpid(pid, NULL, WNOHANG);
        } else
        {
            if(fork() > 0)
            {
                exit(0);
            } else
            {
                OnConnect connect;
                close (msg_sock);
            }
        }
}

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру