The OpenNET Project / Index page

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

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

"Процесный движок"  
Сообщение от tigo email(ok) on 09-Авг-07, 16:11 
Всем доброго времени суток!

Короче это я пытаюсь сделать "процесный движок", софтина должна рождать потомков в количесвеMAXPROC, они засыпают на random() % 100, как только кто нить из потомков заканчивает работу, родитель запускает еще одного потомка, что бы потомков всегда было заданное количество.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <error.h>

#define MAXPROC 4

main()
{
        int pc = MAXPROC;
        int pid = 0;
        int ppid = getpid();

        srand(time(NULL));

        while(1) {

                if(ppid == getpid() && pc > 0) {
                        pc--;
                        pid = fork();
                        printf("(process count %d) PID:%d\n",pc, pid);
                } else {
                        printf("PPID: %d\t PID: %d PC: %d\n", ppid, getpid(), pc);
                        pc = 0;
                }

                switch(pid) {
                        case 0:
                                printf("Child PID: %d\n", getpid());
                                sleep(random() % 100);
                        break;
                        case -1:
                                perror("fork()\n");
                                exit(1);
                        default:
                                if(pc == 0) {
                                        printf("Parent waiting for child with PID %d\n", pid);
                                        wait();
                                        pc++;
                                }
                        break;
                }
        }

}

Работает ли это так как мне надо? Если нет, то почему? И как отлаживать такие приложения?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени, UBB]


1. "Процесный движок"  
Сообщение от anonymous (??) on 09-Авг-07, 16:49 
>Работает ли это так как мне надо? Если нет, то почему? И
>как отлаживать такие приложения?

Дочерние процессы не выходят, а снова попадают в while(1) и ведут себя сами как родители.  Поздравляю, fork-бомба готова!

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Процесный движок"  
Сообщение от tigo email(ok) on 09-Авг-07, 16:53 
>>Работает ли это так как мне надо? Если нет, то почему? И
>>как отлаживать такие приложения?
>
>Дочерние процессы не выходят, а снова попадают в while(1) и ведут себя
>сами как родители.  Поздравляю, fork-бомба готова!

Ну не совсем так...
там проверочка на чилда, если чилд то каунтер процесов обнуляеться...
читай пожалуйста внимательно

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Процесный движок"  
Сообщение от anonymous (??) on 09-Авг-07, 17:22 
>Ну не совсем так...
> там проверочка на чилда, если чилд то каунтер процесов обнуляеться...
> читай пожалуйста внимательно

Извиняюсь, я немного запутался.  По-моему, код работает немного неочевидно, и я бы его переписал так:

int child_func()
{
...
}

int main()
{
  int child_count = 0;
  pid_t pid;
  while(1)
  {
    while(child_count < MAXCHILDREN)
    {
      if(pid = fork())
      {
        /* проверяем ошибки */
        child_count++;
      }
      else
      {
        child_func();
        exit(0);
      }
    }
    while(pid == wait(NULL))
    {
      /* для каждого завершенного потомка уменьшаем child_count */
    }
  }
}

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Процесный движок"  
Сообщение от tigo email(ok) on 09-Авг-07, 17:37 
Согласен так логичнее выглядит,
только while(pid == wait(NULL)) ждет только одного потомка и потом стартует тоже только одного.
Интересно которого?


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Процесный движок"  
Сообщение от vic (??) on 09-Авг-07, 16:54 
>>Работает ли это так как мне надо? Если нет, то почему? И
>>как отлаживать такие приложения?
>
>Дочерние процессы не выходят, а снова попадают в while(1) и ведут себя
>сами как родители.  Поздравляю, fork-бомба готова!

нет, там условие:
if(ppid == getpid() && pc > 0) {
т.е. дети не будут форкаться

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Процесный движок"  
Сообщение от vic (??) on 09-Авг-07, 16:58 
>Работает ли это так как мне надо? Если нет, то почему?

Мы не телепаты и не знаем что тебе надо :)
Данный код делает несколько форков и в них спит.

> И как отлаживать такие приложения?

Тщательно и с применением всех доступных средств :)
Хотя что там отлаживать-то, он че падает или делает не то что ожидается?


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Процесный движок"  
Сообщение от tigo email(ok) on 09-Авг-07, 17:03 
>>Работает ли это так как мне надо? Если нет, то почему?
>
>Мы не телепаты и не знаем что тебе надо :)
>Данный код делает несколько форков и в них спит.
>
>> И как отлаживать такие приложения?
>
>Тщательно и с применением всех доступных средств :)
>Хотя что там отлаживать-то, он че падает или делает не то что
>ожидается?

Всегда должно быть количесвто потомков равное.
По порядку,
Рождаеться MAXPROC потомков,
допустим один засыпает на 20сек и второй 60сек и тд
Просыпаеться первый черз 20сек и заверщает работу
надо что бы родитель пускал еще одного вместо него

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Процесный движок"  
Сообщение от vic (??) on 09-Авг-07, 17:33 
>[оверквотинг удален]
>>Тщательно и с применением всех доступных средств :)
>>Хотя что там отлаживать-то, он че падает или делает не то что
>>ожидается?
>
>Всегда должно быть количесвто потомков равное.
>По порядку,
>Рождаеться MAXPROC потомков,
>допустим один засыпает на 20сек и второй 60сек и тд
>Просыпаеться первый черз 20сек и заверщает работу
>надо что бы родитель пускал еще одного вместо него

Проснувшись потомок идет на while(1), т.е. не завершается.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Процесный движок"  
Сообщение от tigo email(ok) on 09-Авг-07, 17:35 
>[оверквотинг удален]
>>>ожидается?
>>
>>Всегда должно быть количесвто потомков равное.
>>По порядку,
>>Рождаеться MAXPROC потомков,
>>допустим один засыпает на 20сек и второй 60сек и тд
>>Просыпаеться первый черз 20сек и заверщает работу
>>надо что бы родитель пускал еще одного вместо него
>
>Проснувшись потомок идет на while(1), т.е. не завершается.

ага уже понял )

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Процесный движок"  
Сообщение от vic (??) on 09-Авг-07, 17:39 
>[оверквотинг удален]
>>>ожидается?
>>
>>Всегда должно быть количесвто потомков равное.
>>По порядку,
>>Рождаеться MAXPROC потомков,
>>допустим один засыпает на 20сек и второй 60сек и тд
>>Просыпаеться первый черз 20сек и заверщает работу
>>надо что бы родитель пускал еще одного вместо него
>
>Проснувшись потомок идет на while(1), т.е. не завершается.

И сразу же вопрос, зачем породив N процессов делать завершение и новый форк для них? Не лучше ли если процесс выполнив задачу просто снова засыпает?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "Процесный движок"  
Сообщение от tigo email(ok) on 09-Авг-07, 17:44 
>[оверквотинг удален]
>>>Рождаеться MAXPROC потомков,
>>>допустим один засыпает на 20сек и второй 60сек и тд
>>>Просыпаеться первый черз 20сек и заверщает работу
>>>надо что бы родитель пускал еще одного вместо него
>>
>>Проснувшись потомок идет на while(1), т.е. не завершается.
>
>И сразу же вопрос, зачем породив N процессов делать завершение и новый
>форк для них? Не лучше ли если процесс выполнив задачу просто
>снова засыпает?

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

26. "Процесный движок"  
Сообщение от Ray Dudu on 13-Авг-07, 19:21 
>>[оверквотинг удален]
>Задумка такая ) некя чилд функция получает в качестве параметра элемент структуры,
>производит с ней операции и завершае работу, след аналогично. Что бы
>обработка элементов не повторялась, нечто похожее на такой способ синхронзации. Може
>есть другие варианты.. я не давно занимаюсь программированием.

вопрос 1: нужны ли тебе тут вообще процессы, может проще взять потоки? Для ОС легче их создавать. вопрос 2: зачем тебе каждый раз перезапускать процесс,может ему проще получать данные используя какойнить shared memory or pipes?
поразмысль над этим

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "Процесный движок"  
Сообщение от elvenic (??) on 09-Авг-07, 18:36 
> И как отлаживать такие приложения?

А отлаживать - syslog()'ом (man 3 syslog). И печатать timestamps с точностью до микросекунды. (Чем и я сам сейчас, кстати, и занимаюсь :) )

Have fun!

    elvenic.


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

13. "Процесный движок"  
Сообщение от tigo email(ok) on 09-Авг-07, 19:32 
В итоге поучилось нечто такое, если где то есть ошибка сообщите. Всем спасибо за участие.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAXPROC 4                                                       /* Максимальное количество процессов*/
#define WTIME   30                                                      /* Время работы процесса максимальное*/

main()
{
        pid_t pid = 0;                                                  /* PID процесса потомка*/
        pid_t cpid = getpid();                                          /* PID родителя всех потомков в данном процессе */
        unsigned status = 0;
        srand(time(NULL));


        unsigned char child_proc_count = 0;
        while(1) {
                if(cpid == getpid() && child_proc_count < MAXPROC ) {   /* Если этот процесс первый */
                        child_proc_count++;                             /* Увеличиваем счетчик потомков*/
                        pid = fork();                                   /* Рождение потомка */
                }
                switch(pid) {
                        case 0:                                         /* Код потомка */
                                printf("Пороцесс потомок PID=%d\n", getpid());
                                sleep(random() % WTIME);                /* Полезная работа потомка*/
                                exit(status);                           /* Окончание работы потомка со статусом 0 */
                        break;
                        default:
                                if(child_proc_count == (MAXPROC - 1)) {
                                                                        /* Ожидае пока потомок закончит работу со статусом 0 */
                                        printf("Запущенно потомков - %d\n Ждем окончание работы потомка PID=%d\n", child_proc_count, wait(&status));
                                        child_proc_count--;             /* Уменьшаем количество потомков */
                                }
                        break;
                }
        }

}

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

14. "Процесный движок"  
Сообщение от anonymous (??) on 10-Авг-07, 02:15 
>В итоге поучилось нечто такое, если где то есть ошибка сообщите. Всем
>спасибо за участие.

Извиняюсь за наглость в этом посте, я просто написал всё что я думаю об этом коде, я не хочу вас обидеть ни в коей мере.

Я уже показал как обычно делаются такие вещи в предыдущем посте.  А именно:

if(pid == fork())
{
  это родитель, проверяем ошибки
}
else
{
  это потомок, делаем работу и обязательно выходим!
}

Вот эта конструкция является идиомой в программировании, её умеют "увидеть" сотни и тысячи программистов.  Облегчите поддержку вашего кода :)

В вашем коде:
if(cpid == getpid() && child_proc_count < MAXPROC ) {   /* Если этот процесс первый */
вот эту строку я сначала без комментария вообще не понял, и поэтому неправильно сказал что это форк-бомба, за что мне очень стыдно.  К тому же, при каждом шаге цикла вызывается getpid(), без которого можно обойтись (в моём коде его нет)

child_proc_count++;                             /* Увеличиваем счетчик потомков*/
нелогично, в этот момент потомка ещё нет и неизвестно -- может даже не хватит памяти его создать

pid = fork();                                   /* Рождение потомка */
см. выше насчёт идиомы программирования

switch из 0 и default это эффективно является тем же if() что и в идиоме, только это снова неочевидно

printf("Запущенно потомков - %d\n Ждем окончание работы потомка PID=%d\n", child_proc_count, wait(&status));
вынесите wait() в отдельную строку и сделайте проверку ошибок.  логически (с первого взгляда) эта строка кода выводит текст, а реально -- ждёт потомка и только потом выводит текст. (фактически, изменяется способ исполнения программы -- она засыпает, нужно это подчеркнуть)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

15. "Процесный движок"  
Сообщение от jd (??) on 10-Авг-07, 06:19 
Я бы всё-таки написал:

switch(pid = fork())
{ case -1: /* ошибка */
    ...
    break;
  case 0: /* дочерний процесс */
    ...
    exit(...);
  default: /* родитель */
    ...
    break;
}

И у вас тут опечатка: "if(pid == fork())"

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

17. "Процесный движок"  
Сообщение от tigo email(ok) on 10-Авг-07, 09:33 
>[оверквотинг удален]
>см. выше насчёт идиомы программирования
>
>switch из 0 и default это эффективно является тем же if() что
>и в идиоме, только это снова неочевидно
>
>printf("Запущенно потомков - %d\n Ждем окончание работы потомка PID=%d\n", child_proc_count, wait(&status));
>вынесите wait() в отдельную строку и сделайте проверку ошибок.  логически (с
>первого взгляда) эта строка кода выводит текст, а реально -- ждёт
>потомка и только потом выводит текст. (фактически, изменяется способ исполнения программы
>-- она засыпает, нужно это подчеркнуть)

Действительн, огромное спасибо за полезные комментарии, я не очень давно программирую на Си :-) и с удовольствием приму Ваши комментарии к сведению, и поступлю в соответсвии с ними. У самого голова пухнет от чтения чужих кодов... В любом случае это еще не оконченный продукт и в данном виде, так сказать, существует только на бумаге и ввиде учебного примера(для меня же :-). А в общем, очень рад на такую реакцию знаменитого сообщества ) Большое вам спасибо, Вашими стараниями и из меня получиться хороший программист!

PS Так настроение поднял сутра )

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

16. "Процесный движок"  
Сообщение от phpcoder email(??) on 10-Авг-07, 09:12 
[...]
>#include <stdio.h>
>#include <stdlib.h>
>#include <time.h>
>#include <error.h>

[...]

error.h тут лишний.

Также нехватает нескольких хедеров:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

18. "Процесный движок"  
Сообщение от anonymous (??) on 10-Авг-07, 12:35 
>error.h тут лишний.

Наверное, имелось ввиду errno.h.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

19. "Процесный движок"  
Сообщение от phpcoder email(??) on 10-Авг-07, 12:39 
>>error.h тут лишний.
>
>Наверное, имелось ввиду errno.h.

Даже если и так -- errno.h был бы тоже лишним :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

20. "Процесный движок"  
Сообщение от tigo email(ok) on 10-Авг-07, 12:46 
>>error.h тут лишний.
>
>Наверное, имелось ввиду errno.h.

А в чем разница?

У Б. Моли в "Unix/Linux. Теория и практика программирования."
perror() применяеться ваапсче без подключения ни errno.h ни error.h )
у меня компилер ругаеться если я их не включаю и использую что то из этих фалов, хотя собирает и работает )

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

21. "Процесный движок"  
Сообщение от phpcoder email(??) on 10-Авг-07, 12:49 
>>>error.h тут лишний.
>>
>>Наверное, имелось ввиду errno.h.
>
>А в чем разница?

man 3 errno
man 3 error

>У Б. Моли в "Unix/Linux. Теория и практика программирования."
> perror() применяеться ваапсче без подключения ни errno.h ни error.h )

У меня в man'е написано, что perror() находится в stdio.h


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

23. "Процесный движок"  
Сообщение от tigo email(ok) on 10-Авг-07, 13:04 
>[оверквотинг удален]
>>
>>А в чем разница?
>
>man 3 errno
>man 3 error
>
>>У Б. Моли в "Unix/Linux. Теория и практика программирования."
>> perror() применяеться ваапсче без подключения ни errno.h ни error.h )
>
>У меня в man'е написано, что perror() находится в stdio.h

а какой пакет поставить? у меня таких man'ов нет...
tigo@box:~/proj$ cat /etc/debian_version
4.0
tigo@box:~/proj$ uname -a
Linux box 2.6.18-4-686 #1 SMP Mon Mar 26 17:17:36 UTC 2007 i686 GNU/Linux
Установка с одного компакта debian-40r0-i386-xfce-CD-1.iso

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

24. "Процесный движок"  
Сообщение от phpcoder email(??) on 10-Авг-07, 13:18 
[...]
>а какой пакет поставить?

Что-нибудь вроде man-pages и man-pages-ru

Поищите с помощью apt-cache search man-page

>у меня таких man'ов нет...

У меня, в ALT Linux, в пакетах man-pages, man-pages-ru и man-pages-POSIX

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

25. "Процесный движок"  
Сообщение от tigo email(ok) on 10-Авг-07, 13:27 
>[...]
>>а какой пакет поставить?
>
>Что-нибудь вроде man-pages и man-pages-ru
>
>Поищите с помощью apt-cache search man-page
>
>>у меня таких man'ов нет...
>
>У меня, в ALT Linux, в пакетах man-pages, man-pages-ru и man-pages-POSIX

нашел, спасибо

apt-get install manpages-dev

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

22. "Процесный движок"  
Сообщение от anonymous (??) on 10-Авг-07, 12:57 
>>>error.h тут лишний.
>>
>>Наверное, имелось ввиду errno.h.
>
>А в чем разница?

Откройте /usr/include/error.h и посмотрите -- ничего полезного (сейчас) там для вас нет :)

А в man errno написано, что она в errno.h

>У Б. Моли в "Unix/Linux. Теория и практика программирования."
> perror() применяеться ваапсче без подключения ни errno.h ни error.h )
> у меня компилер ругаеться если я их не включаю и использую
>что то из этих фалов, хотя собирает и работает )

Наверное это сделано для краткости примеров (в книге исходники печатать...)

А вот в настоящих программах компилятор ругаться не должен, нужно писать так "чисто и аккуратно", как только можно.  Поэтому читаем man perror и согласно нему включаем stdio.h (да, у вас он уже есть)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




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

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