Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C] Создание процессов 
V
    Опции темы
DeathKnight
Дата 8.9.2010, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 12.10.2007
Где: Минск

Репутация: нет
Всего: нет



необходимо написать программу, которая создает два процесса. те, в свою очередь, должны выводить системное время в разных углах консольного окна.
реализовать надо под винду и линукс.
вопрос такой: в какую сторону копать, какие нужны ф-ии и какие есть нюансы?
заранее благодарю.
PM   Вверх
djamshud
Дата 8.9.2010, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 1
Всего: 39



Linux: fork для создания дочернего процесса-себя-же, ncurses для рисования в консоли. Если хочется запустить совсем другой процесс, то fork+execv.

Добавлено через 50 секунд
Нюанс есть: заставить два процесса рисовать в одну консоль.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
ller
Дата 10.9.2010, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

Репутация: нет
Всего: 4



Процессы или потоки?
PM MAIL   Вверх
DeathKnight
Дата 10.9.2010, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 12.10.2007
Где: Минск

Репутация: нет
Всего: нет



Цитата(ller @ 10.9.2010,  20:45)
Процессы или потоки?

Цитата

Процессы или потоки?


процессы.

Код

#include <windows.h>
#include <iostream>
#include <iomanip>
#include <TCHAR.h>
#include <time.h>
#include <conio.h>



using namespace std;

int _tmain( int argc, TCHAR *argv[] )
{
    int temp;
    STARTUPINFO si1, si2;
    PROCESS_INFORMATION pi1, pi2;
    TCHAR *pi1cl;
    TCHAR *pi2cl;
    ZeroMemory( &si1, sizeof(si1) );
    ZeroMemory( &si2, sizeof(si2) );
    si1.cb = sizeof(si1);
    si2.cb = sizeof(si2);
    ZeroMemory( &pi1, sizeof(pi1) );
    ZeroMemory( &pi2, sizeof(pi2) );

    if( argc < 2 )
    {
        pi1cl=(TCHAR*)calloc(4, sizeof(TCHAR));
        lstrcpy(pi1cl, L"1");
        /*
        si1.dwX = 0;
        si1.dwY = 0;
        si1.dwXCountChars = 40;
        si1.dwYCountChars = 25;
        si1.dwFlags = STARTF_USEPOSITION | STARTF_USECOUNTCHARS;
        */
        temp=CreateProcess( 
             argv[0],                // No module name (use command line)
             pi1cl,                    // Command line
             NULL,                    // Process handle not inheritable
             NULL,                    // Thread handle not inheritable
             FALSE,                    // Set handle inheritance to FALSE
             0, //CREATE_NEW_CONSOLE,    
             NULL,                    // Use parent's environment block
             NULL,                    // Use parent's starting directory 
             &si1,                    // Pointer to STARTUPINFO structure
             &pi1 );
        if( !temp) 
        {
            cout << "CreateProcess failed.\n" << endl;
            return 0;
        }else
        {
            cout << "Process 1 created" << endl;
        }
                
        pi2cl=(TCHAR*)calloc(4, sizeof(TCHAR));
        lstrcpy(pi2cl, L"2");
        /*
        si2.dwX = 41;
        si2.dwY = 0;
        si2.dwXCountChars = 40;
        si2.dwYCountChars = 25;
        si2.dwFlags = STARTF_USEPOSITION | STARTF_USECOUNTCHARS;
        */
        if( !CreateProcess( 
             argv[0],                // No module name (use command line)
             pi2cl,                    // Command line
             NULL,                    // Process handle not inheritable
             NULL,                    // Thread handle not inheritable
             FALSE,                    // Set handle inheritance to FALSE
             0, //CREATE_NEW_CONSOLE,
             NULL,                    // Use parent's environment block
             NULL,                    // Use parent's starting directory 
             &si2,                    // Pointer to STARTUPINFO structure
             &pi2 )                    // Pointer to PROCESS_INFORMATION structure
            ) 
        {
            printf( "CreateProcess failed.\n", GetLastError() );
            TerminateProcess((HANDLE)pi1.dwProcessId, 0);
            return 0;
        }else
        {
            cout << "Process 2 created" << endl;
        }

        HANDLE piMas[2];
        piMas[0]=(HANDLE)pi1.dwProcessId;
        piMas[1]=(HANDLE)pi2.dwProcessId;

        //WaitForMultipleObjects(2, piMas, true, INFINITE);
        WaitForSingleObject((HANDLE)pi1.dwProcessId, INFINITE);

        CloseHandle( pi1.hProcess );
        CloseHandle( pi1.hThread );
        cout << "First process closed." << endl;
        CloseHandle( pi2.hProcess );
        CloseHandle( pi2.hThread );
        cout << "Second process closed." << endl;
        
        system("pause");
        return 0;
    }
    else
    {
        if(!lstrcmp(argv[1], L"1"))
        {
            char timestr[10];
            do
            {
                _strtime_s( timestr, 9 );
                cout << setiosflags(ios::left) 
                     << timestr
                     << resetiosflags(ios::left) << endl;
                Sleep(700);
            }while(!_kbhit());
        }

        if(!lstrcmp(argv[1], L"2"))
        {
            char timestr[10];
            do
            {
                _strtime_s( timestr, 9 );
                cout << setiosflags(ios::right) 
                     << setw(39)
                    << timestr
                     << resetiosflags(ios::right) << endl;
                Sleep(700);
            }while(1);
        }
    }
    return 0;
}



вот набросал код для win, но найти ошибки не могу. что я упустил?
PM   Вверх
DeathKnight
Дата 10.9.2010, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 12.10.2007
Где: Минск

Репутация: нет
Всего: нет



Цитата(djamshud @  8.9.2010,  16:27 Найти цитируемый пост)
Нюанс есть: заставить два процесса рисовать в одну консоль. 


как это можно сделать?
PM   Вверх
ИванМ
Дата 12.9.2010, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 13
Всего: 23



Цитата(DeathKnight @  10.9.2010,  21:24 Найти цитируемый пост)
как это можно сделать? 

Смотри в сторону синхронизации. В инете на эту тему много инфы.
На счет ошибки, то скажи какая конкретно.
PM MAIL   Вверх
DeathKnight
Дата 13.9.2010, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 12.10.2007
Где: Минск

Репутация: нет
Всего: нет



в общем вот:
под линь:
Код

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

int main(void)
{
 initscr();
 clear();
 refresh(); 
 pid_t cpid=fork(); 

 if(cpid==0)
 {    
    do
    {
    time_t t = time(NULL);
    char* s=ctime(&t);
    mvaddstr(0,0,s);
    refresh();    
    }
    while(1);
  }
  else 
  {    
    do
    {
    time_t t = time(NULL);
    char* s=ctime(&t);
    mvaddstr(0,40,s);
    refresh();    
    }
    while(1);
  };
return 1;
}


и под винду:
Код

#include <windows.h>
#include <iostream>
#include <iomanip>
#include <TCHAR.h>
#include <time.h>
#include <conio.h>

using namespace std;

int _tmain( int argc, TCHAR *argv[] )
{
    int temp;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    ZeroMemory(&pi, sizeof(pi));
    si.cb = sizeof(si);
    TCHAR picl[100];
    ZeroMemory(&picl, 100);

    temp = (int)CreateMutex(NULL, FALSE, L"8e07e18e-11e8-4e48-9c08-cc91d05f6ad8");
    temp = GetLastError();
    if(temp == ERROR_ALREADY_EXISTS || temp == ERROR_ACCESS_DENIED)
    {
        char timestr[10];
        COORD ch;
        ch.X=0;
        ch.Y=0;
        do
        {
            temp = (int)GetConsoleWindow();
            SetConsoleCursorPosition((HANDLE)temp, ch);
            _strtime_s( timestr, 9 );
            cout << setiosflags(ios::left)
                 << "child process: "
                 << timestr
                 << resetiosflags(ios::left) << endl;
            Sleep(700);
        }while(!kbhit());
        return 0;
    }
    else
    {
        temp = CreateProcess(argv[0], picl, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi);
        if(temp != 0)
        {
            char timestr[10];
            COORD pr;
            pr.X=40;
            pr.Y=0;
            do
            {
                    temp = (int)GetConsoleWindow();
                    temp = SetConsoleCursorPosition((HANDLE)temp, pr);
                    _strtime_s( timestr, 9 );
                    cout << setiosflags(ios::right) 
                         << setw(60)
                         << "parent process: "
                         << timestr
                         << resetiosflags(ios::right) << endl;
                    Sleep(600);
            }while(!kbhit());
        }
        else return 0;
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);

    }
    return 0;
}


в общем все работает. но не разобрался с выводом под винду. там не получается установить курсор, в итоге вместо одной строки получается последовательность.
PM   Вверх
DeathKnight
Дата 17.9.2010, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 12.10.2007
Где: Минск

Репутация: нет
Всего: нет



теперь сделал нормально. если кому будет нужно:
Код

#include <windows.h>
#include <TCHAR.h>
#include <time.h>
#include <stdio.h>
#include <conio.h>

int _tmain( int argc, TCHAR *argv[] )
{
    int temp;                                        // переменная для получения кодов ошибок
    HANDLE mutex;                                    // дескриптор мьютекса
    STARTUPINFO si;                                    // окружение для дочернего процесса
    PROCESS_INFORMATION pi;                            // описание процесса дочернего процесса
    ZeroMemory(&si, sizeof(si));                    // очистка структур
    ZeroMemory(&pi, sizeof(pi));
    si.cb = sizeof(si);
    TCHAR picl[100];
    ZeroMemory(&picl, 100);
    HANDLE hInput, hOutput;

    mutex = CreateMutex(NULL, FALSE, L"8e07e18e-11e8-4e48-9c08-cc91d05f6ad8"); // создание именного объекта мьютекса
    temp = GetLastError();
    if(temp == ERROR_ALREADY_EXISTS || temp == ERROR_ACCESS_DENIED)               // цикл работы дочернего процесса
    {
        char timestr[10];
        COORD ch;
        ch.X=0;
        ch.Y=0;
        do
        {
            temp = WaitForSingleObject(mutex, INFINITE);                       // ожидание и получение доступа к мьютексу
            switch(temp)
            {
                case WAIT_OBJECT_0:                                               // доступ получен    
                    {
                        hInput = GetStdHandle(STD_INPUT_HANDLE); 
                        hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
                        _strtime_s( timestr, 9 );
                        SetConsoleCursorPosition(hOutput,ch);
                        printf("child process: %s", timestr);
                        Sleep(500);
                        ReleaseMutex(mutex);
                        break;
                    }
            }
        }while(!_kbhit());
        CloseHandle(mutex);
        return 0;
    }
    else        // родительский цикл
    {
        temp = CreateProcess(argv[0], picl, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi); // создание дочернего процесса
        if(temp != 0)
        {
            char timestr[10];
            COORD pr;
            pr.X=40;
            pr.Y=0;
            do
            {
                temp = WaitForSingleObject(mutex, INFINITE);
                switch (temp)
                {
                    case WAIT_OBJECT_0:
                        {
                            hInput = GetStdHandle(STD_INPUT_HANDLE); 
                            hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
                            _strtime_s( timestr, 9 );
                            SetConsoleCursorPosition(hOutput, pr);
                            printf("parent process: %s", timestr);
                            ReleaseMutex(mutex);
                            Sleep(500);
                            break;
                        }
                }
            }while(!_kbhit());
        }
        else return 0;
        WaitForSingleObject(pi.hProcess, INFINITE);            // ожидание завершения дочернего процесса
        CloseHandle(pi.hProcess);                            // закрытие дескрипторов объектов ядра
        CloseHandle(mutex);
    }
    return 0;
}


Код

#include <time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <curses.h>
#include <unistd.h>
#include <signal.h>

void sig_winch(int signo)                                // обработка сигнала изменения окна
{
    struct winsize size;                                // структура "размер окна"
    ioctl(fileno(stdout), TIOCGWINSZ, (char *) &size);  // получение данных о новых размерах окна
    resizeterm(size.ws_row, size.ws_col);                // обновление содержимого окна в соответствии с новыми размерами
}

void win_draw(WINDOW * pwnd, int row, int col)            // вывод в опр. окно в опр. координаты
{
    WINDOW *wnd;                                        // дескриптор окна
    wnd = derwin(pwnd, 5, 30, row, col);                // создание под-окна
    wrefresh(wnd);                                        // обновление под-окна

    time_t _time = time(NULL);                            // получение времени
    char * _ctime = ctime(&_time);                        // формирование строки
    mvwaddstr(wnd, 0, 0, _ctime);                        // вывод строки в под-окно
    delwin(wnd);    
    sleep(0.4);
}

int main()
{
    WINDOW * wnd;                                     // дескриптор окна терминала
    bool temp;                                            
    wnd = initscr();                                    // инициализация библиотеки
    signal(SIGWINCH, sig_winch);                        // установка обработчика сигнала
    cbreak();                                            // ввод с клавиатуры моментальный, не дожидаясь ENTER
    attron(A_UNDERLINE);                                // установка параметров текста, подчеркнутый
    curs_set(0);                                        // "выключение" курсора
    clear();                                            // очистка экрана
    refresh();                                            // вывод изменений
    
    pid_t _pid = fork();                                // порождение дочернего процесса
    if (_pid != -1)
    {    
        while(1)
        {
            if (_pid)                                    // если родительский
            {
                if(!temp)
                {
                    sleep(1);
                    temp=true;
                }
                win_draw(wnd, 0, 45);
                sleep(0.1);
            }
            else                                        // дочерний
            {    
                win_draw(wnd, 0, 0);
            }
        }
        if (_pid)
        {
            kill(_pid, SIGKILL);                        // убийство дочернего
        }
    }
    else
    {
        printf("Occured fork()-error");
    }
    endwin();                                            // очистка параметров библиотеки
    system("clear");                                    // чистка экрана системными ф-ями
    return 0;
}



Это сообщение отредактировал(а) DeathKnight - 17.9.2010, 23:09
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0898 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.