Рекурсивное создание процесса

Тема в разделе "WASM.WIN32", создана пользователем wild89, 27 мар 2010.

  1. wild89

    wild89 New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    15
    Всем доброго времени суток.
    Задача такая: Заставьте консольный процесс запустить несколько своих копий (и далее рекурсивно). Убедитесь, что порождение процессов не будет бесконечным (остановитесь на 4 уровнях максимум)
    Вопрос состоит в следующем: как мне именно остановить рекурсию после создания 4 процесса? Подскажите пожалуйста, жду ответов, заранее спасибо.
     
  2. l3Ta0n

    l3Ta0n New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2009
    Сообщения:
    45
    считай количество процессов в системе с твоим именем.
     
  3. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    семафор со счетчиком = 4
     
  4. G13

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
  5. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    либо shared секция с переменной-счетчиком
     
  6. wild89

    wild89 New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    15
    Решил попробывать с семафором. Идея показалась простой, а вот реализация у меня вызывает затруднения:dntknw:((
    Чесно скажу в программировании новичок, а здать лабу надо. Исправте или подскажите на мои ошибки в коде.

    Вроде - бы все должно быть просто: создаю семафор с макс. числом обращений равное 4, потом создаю процесс и увеличиваю счетчик на 1.
    Но на самом деле запускается куча процессов и система виснет:dntknw:
    int main(int argc, char **argv)
    {

    DWORD dwWaitResult;
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;

    si.lpTitle = "Daughter process";
    si.dwFlags = STARTF_USEFILLATTRIBUTE|STARTF_USEPOSITION|STARTF_USESIZE;
    si.dwXSize = 800;
    si.dwYSize = 300;


    HANDLE hSem = CreateSemaphore(NULL, 0, 4, "MySem");

    CreateProcess(argv[0], NULL, NULL, NULL, TRUE,CREATE_NEW_CONSOLE|NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);

    ReleaseSemaphore(hSem,1,NULL);

    getchar();

    return 0;
    }
     
  7. wild89

    wild89 New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    15
    Эм...ну подскажите хоть кто-нибудь? В чем ошибка?
    Код (Text):
    1. int main(int argc, char **argv)
    2. {
    3.  
    4.   DWORD dwWaitResult;
    5.   STARTUPINFO si = { sizeof(si) };
    6.   PROCESS_INFORMATION pi;
    7.  
    8.   si.lpTitle        = "Daughter process";
    9.   si.dwFlags        = STARTF_USEFILLATTRIBUTE|STARTF_USEPOSITION|STARTF_USESIZE;
    10.   si.dwXSize        = 800;
    11.   si.dwYSize        = 300;
    12.  
    13.  
    14. HANDLE hSem = CreateSemaphore(NULL, 1, 4, "MySem");
    15.  
    16. OpenSemaphore(SEMAPHORE_ALL_ACCESS,TRUE, "MySem");
    17.  
    18. cout<<"Proverka sostoyania semafora\n";
    19.  
    20. WaitForSingleObject(hSem, INFINITE);
    21.  
    22. cout<<"polu4en dostup\n";
    23.  
    24. CreateProcess(argv[0], NULL, NULL, NULL, TRUE,CREATE_NEW_CONSOLE|NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
    25. Sleep(2000);
    26. ReleaseSemaphore(hSem,1,NULL);
    27.  
    28. getchar();
    29.  
    30. return 0;
    31. }
     
  8. l3Ta0n

    l3Ta0n New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2009
    Сообщения:
    45
    может каждый раз создаешь новый семафор, а нужно сначала попытаться открыть старый, ранее созданый.
     
  9. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    wild89
    Не теряй:
    set i=0 && set s="set /a i=i+1 && if ^!i^! NEQ 4 start cmd /k %s%" && cmd /k !s!

    Лол.
     
  10. wild89

    wild89 New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    15
    Sol_Ksacap
    Что это?:dntknw:
     
  11. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Код (Text):
    1. #include <windows.h>
    2. #include <stdio.h>
    3. #include <tchar.h>
    4.  
    5. #define NUM_LEVELS 4
    6. #define NUM_CHILDS 2
    7.  
    8. int _tmain(int argc, const TCHAR *argv[])
    9. {
    10.     SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
    11.  
    12.     HANDLE hSem = CreateSemaphore(&sa, NUM_LEVELS, NUM_LEVELS, TEXT("MySym"));
    13.  
    14.     if (WaitForSingleObject(hSem, 0) == WAIT_OBJECT_0)
    15.     {
    16.         PROCESS_INFORMATION pi = {0};
    17.         STARTUPINFO         si;
    18.         TCHAR szModuleName[MAX_PATH];
    19.  
    20.         HANDLE ahProcesses[NUM_CHILDS];
    21.         HANDLE ahThreads[NUM_CHILDS];
    22.         unsigned i;
    23.  
    24.         GetModuleFileName(NULL, szModuleName, MAX_PATH);
    25.         GetStartupInfo(&si);
    26.         _tprintf(__T("Creating childrens...\n"));
    27.         Sleep(2000);
    28.         for (i = 0; i < NUM_CHILDS; ++i)
    29.         {
    30.             CreateProcess(szModuleName, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL,
    31.                 &si, &pi);
    32.             ahProcesses[i] = pi.hProcess;
    33.             ahThreads[i] = pi.hThread;
    34.         }
    35.         _tprintf(__T("Done.\n"));
    36.         WaitForMultipleObjects(NUM_CHILDS, ahProcesses, TRUE, INFINITE);
    37.         for (i = 0; i < NUM_CHILDS; ++i)
    38.         {
    39.             CloseHandle(ahThreads[i]);
    40.             CloseHandle(ahProcesses[i]);
    41.         }
    42.     }
    43.     Sleep(INFINITE);
    44.     return 0;
    45. }
    Показана лишь идея, не могу сейчас думать, как сделать заполнение уровней целиком, чтобы получилось полное дерево. Оставим это дело ТС.
     
  12. wild89

    wild89 New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    15
    l3Ta0n
    Попробывал твой совет, всеравно не получается.
    Код (Text):
    1. int main(int argc, char **argv)
    2. {
    3.   HANDLE hSem;
    4.   DWORD dwWaitResult;
    5.   HANDLE hMutex;
    6.   STARTUPINFO si = { sizeof(si) };
    7.   PROCESS_INFORMATION pi;
    8.  
    9.   si.lpTitle        = "Daughter process";
    10.   si.dwFlags        = STARTF_USEFILLATTRIBUTE|STARTF_USEPOSITION|STARTF_USESIZE;
    11.   si.dwXSize        = 800;
    12.   si.dwYSize        = 300;
    13.  
    14.   hSem = OpenSemaphore(SEMAPHORE_ALL_ACCESS,TRUE, "MySem");
    15.  
    16.   if(!hSem)
    17.   {
    18.       hSem = CreateSemaphore(NULL,1, 4, "MySem");
    19.     //ReleaseSemaphore(hSem,1,NULL);
    20.   }
    21.   else{
    22.     WaitForSingleObject(hSem, INFINITE);
    23.     ReleaseSemaphore(hSem,1,NULL);
    24.   }
    25.  
    26. Sleep(2000);
    27. CreateProcess(argv[0], NULL, NULL, NULL, TRUE,CREATE_NEW_CONSOLE|NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
    28.  
    29.  
    30. getchar();
    31.  
    32. return 0;
    33. }
     
  13. l3Ta0n

    l3Ta0n New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2009
    Сообщения:
    45
    Всё оказалось проще чем я ожидал. функция ReleaseSemaphore возвращает количство запущенных процессов))
    Код (Text):
    1. #include "windows.h"
    2. #include <iostream>
    3.  
    4. using namespace std;
    5.  
    6. int main(int argc, char **argv)
    7. {
    8.  
    9.   DWORD dwWaitResult;
    10.   STARTUPINFO si = { sizeof(si) };
    11.   PROCESS_INFORMATION pi;
    12.  
    13.   si.lpTitle        = "Daughter process";
    14.   si.dwFlags        = STARTF_USEFILLATTRIBUTE|STARTF_USEPOSITION|STARTF_USESIZE;
    15.   si.dwXSize        = 800;
    16.   si.dwYSize        = 300;
    17.  
    18. int MaxApplicationCount =4;
    19.  
    20. HANDLE ApplicationCountSemaphore = CreateSemaphore(NULL, 0, MaxApplicationCount,  "MySem");
    21. if(ApplicationCountSemaphore == NULL)
    22. {
    23.    
    24. }
    25.  
    26.  
    27. int GlobalApplicationCount;
    28.  
    29. ReleaseSemaphore(ApplicationCountSemaphore, 1, (LPLONG)&GlobalApplicationCount);
    30. cout<<GlobalApplicationCount<<"\n";
    31.  
    32. if(GlobalApplicationCount<MaxApplicationCount){
    33.     cout<<GlobalApplicationCount<<"\n";
    34.     Sleep(2000);
    35.     CreateProcess(argv[0], NULL, NULL, NULL, TRUE,CREATE_NEW_CONSOLE|NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
    36. }
    37.  
    38.  
    39. cout<<"Finished";
    40. getchar();
    41.  
    42. return 0;
    43. }
    Удачи!
     
  14. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    KeSqueer
    А нечего было идти на поводу и делать реализацию с семафором. :derisive: Рекурсия она на то и рекурсия, чтобы работать с локальными для каждой инстанции данными, а не с глобальными объектами. Хотя, если я правильно понял, "дерево" должно быть унарным. :)
    В любом случае городить огород с глобальными объектами ИМХО сложнее, чем передать параметр в процесс в качестве уровня вложенности вызова.
    1) Простейший способ это сделать — использовать какой-нибудь бесполезный параметр из STARTUPINFO (указанные элементы этой структуры будут отображены в PEB дочернего процесса): например, hStdError (при этом не забыть указать валидные hStdInput/hStdOutput).
    2) Ещё один простой способ — инкрементировать переменную окружения через GetEnvironmentVariable/SetEnvironmentVariable.
    3) Также работоспособный вариант — передавать параметр прямо через командную строку.
     
  15. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    l_inc
    Если я правильно понял, ТС не понял условия задачи, и дерево должно быть полным:
    Заставьте консольный процесс запустить несколько своих копий (и далее рекурсивно). Убедитесь, что порождение процессов не будет бесконечным (остановитесь на 4 уровнях максимум)
    1), 2) и 3) - IMHO, не кошерно.
    P.S.
    С каких пор в Российских ВУЗах преподают программирование под Win32?
     
  16. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    KeSqueer
    Унарное дерево всегда полное. :) Мало того... оно ещё и всегда совершенное. :) Но да... наверное, Вы правы, и дерево должно быть как минимум бинарным. Ну так это тем более говорит в пользу того, что параметр глубины вложенности должен быть локальным для процесса.
    Ну 1) — понятно (хотя самый простой вариант): не для этих целей параметры там предназначены. 3) — понятно... мало ли какую командную строку пользователь захочет передать. А чем уже 2) не кошерно?
     
  17. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    l_inc
    Ну, да, это я подразумевал...
    Чем 2) лучше способа с семафорами? Где уровень вложенности определяется по результату ReleaseSemaphore.
    P.S.
    Ну вообще-то 2) просто попал под раздачу. Раз уж спорить, то основательно :)
     
  18. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    KeSqueer
    Видимо тем, что уровень вложенности не определяется по результату ReleaseSemaphore :) (максимум - число живых процессов). Как раз в силу глобальности семафора.
     
  19. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Хорошо, Ваша взяла.
     
  20. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Но все же можно с помощью несложный арифметических действий получить из результата ReleaseSemaphore уровень.