Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: [C++] Процессы  (Прочитано 28573 раз)
0 Пользователей и 15 Гостей смотрят эту тему.
ZWYHB
Участник

ru
Offline Offline

« : 15-01-2010 07:28 » 

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

вот что получилось:
main.cpp
Код: (C++)
#include <iostream>
#include <vector>
#include <unistd.h>
#include <string>
#include <process.h>

using namespace std;

int main(int argc, char *argv[])
{

    cout << "Vvedite kollichestvo programm:"<<endl;
    unsigned n;
    cin>>n;
    std::vector <string> v;
    v.resize(n);
    if(n<=0) return 0;
    cout << "Vvedite imena programm:"<<endl;
    for (int i =0; i<n; ++i)
    {
        cin>>v[i];
    }

f(n,v);
cout<<"end"<<endl;
    return EXIT_SUCCESS;
}

proc.h

Код: (C++)
#ifndef PROCESS_H
#define PROCESS_H
#include<unistd.h>
#include<iostream>
#include <vector>
#include<string>
class Process
{
public:
    Process();
    ~Process() {}
    operator bool() const;
    pid_t id() const;
    bool run(std::string a);
   
protected:
    int action(std::string a);
private:
    Process(pid_t id);
private:
    pid_t pid;
};
inline Process::operator bool() const
{
    return pid != 0;
}
inline pid_t Process::id() const
{
    return pid;
}
void f(int n, std::vector <std::string> v);
#endif

proc.cpp

Код: (C++)
#include "process.h"
#include <cstdlib>
#include <string>
#include <vector>
#include <signal.h>
#include <sys/wait.h>
using namespace std;

Process::Process()
        : pid(0)
{
}
Process::Process(pid_t id)
        : pid(id)
{
}
bool Process::run(std::string a)
{
    if ( pid )
        return false;
    pid = fork();
    switch ( pid )
    {
    case -1:
        pid = 0;
        return false;
    case 0:
        pid = getpid();
        exit(action(a));
    }
    return true;
}

int Process::action(string a)
{
system(a.c_str());
return 0;
}

void f(int n, vector <string> v)
{
vector <Process> p(n);
for(int i=0; i<n;++i)
{
p[i].run(v[i]);
}
return;
}

Всё работает
Но значительную часть этого  взял из методички - вроде понимаю что здесь происходит - но препод придирается
Не могли бы рассписать - что здесь к чему?
Особенно интересуют это :
Код: (C++)
class Process
{
public:
    Process();
    ~Process() {}
    operator bool() const;
    pid_t id() const;
    bool run(std::string a);
   
protected:
    int action(std::string a);
private:
    Process(pid_t id);
private:
    pid_t pid;
};
inline Process::operator bool() const
{
    return pid != 0;
}
inline pid_t Process::id() const
{
    return pid;
}
void f(int n, std::vector <std::string> v);
#endif
и
Код: (C++)
Process::Process()
        : pid(0)
{
}
Process::Process(pid_t id)
        : pid(id)
{
}
..................
void f(int n, vector <string> v)
{
vector <Process> p(n);
for(int i=0; i<n;++i)
{
p[i].run(v[i]);
}
« Последнее редактирование: 15-01-2010 07:36 от Sel » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 15-01-2010 08:36 » 

А к чему именно препод "придирается", и что тебе нужно объяснить (код тут самый наиочевиднейший)?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ZWYHB
Участник

ru
Offline Offline

« Ответ #2 : 15-01-2010 08:43 » 

ну скажем - для чего вот это :
Код:
Process::Process()
        : pid(0)
{
}
Process::Process(pid_t id)
        : pid(id)
{
}
и
vector <Process> p(n) - это массив векторов
p[i].run(v[i]); -?
« Последнее редактирование: 15-01-2010 08:46 от Вад » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 15-01-2010 08:48 » 

это не массив векторов, а массив(вектор) процессов. И вызывается метод run для каждого элемента этого вектора, при этом i-тый процесс получает v[i] в качестве аргумента метода run.

ну скажем - для чего вот это :
Код:
Process::Process()
        : pid(0)
{
}
Process::Process(pid_t id)
        : pid(id)
{
}
а это два конструктора класса Process: конструктор по умолчанию и конструктор с параметром pid - нужны для создания экземпляра Process, выполняют инициализацию полей объекта.
« Последнее редактирование: 15-01-2010 08:49 от Вад » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 15-01-2010 11:22 » 

Интересно, как можно написать лабу на языке программирования "продолжение которого сам не знаешь" (с) х/ф "Кин-дза-дза"...

В общем, проблема не в процессах и не в лабе, а в незнании языка программирования.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ZWYHB
Участник

ru
Offline Offline

« Ответ #5 : 15-01-2010 13:34 » 

Цитата
В общем, проблема не в процессах и не в лабе, а в незнании языка программирования.
Я только учусь!!

 Вад, ты не мог бы поподробнее написать про вектор процессов?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 15-01-2010 13:47 » 

А что про него подробнее писать? Контейнер из стандартной библиотеки STL, замена обычным динамическим массивам. Построен в виде шаблона - то есть, позволяет адаптировать шаблонную реализацию для хранения элементов любого типа.

Вообще, это настолько естественная часть C++ сейчас, что даже удивительно, почему в методичке он у тебя есть, и при этом требуется объяснять, что это.
Записан
Sla
Модератор

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 15-01-2010 14:07 » 

Тогда нужно объяснить, что такое конструктор. Что такое вектор и т.д.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
ZWYHB
Участник

ru
Offline Offline

« Ответ #8 : 15-01-2010 14:20 » 

Ну вот накинулись!
Знаю я - что такое конструкторы, деструкторы и прочее.
Контейнеры подзабылись.
Записан
Sla
Модератор

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 15-01-2010 14:26 » 

Накинулись? Пытаемся понять, что ты знаешь.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #10 : 16-01-2010 01:43 » 

Что то я не пойму, в чем собственно вопрос...
Записан

С уважением Lapulya
ZWYHB
Участник

ru
Offline Offline

« Ответ #11 : 16-01-2010 08:13 » 

Вот ещё маленький вопрос
Код:
 case 0:
        pid = getpid();
        exit(action(a));
    }
    return true;
Вот здесь - я правильно понимаю - в случае если мы в потомке - получаем идентификатор процесса, выполняем action и выходим?
pid = getpid(); - что конкретно означает?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 16-01-2010 09:06 » new

У тебя Process хранит pid для запускаемого процесса. fork возвращает 0 в экземпляр дочернего процесса. И функция getpid вызывается, чтобы узнать pid текущего процесса.
Записан
ZWYHB
Участник

ru
Offline Offline

« Ответ #13 : 16-01-2010 09:18 » 

спасибо!
Записан
ZWYHB
Участник

ru
Offline Offline

« Ответ #14 : 16-01-2010 13:58 » 

А для чего надо объявлять эти методы константными:
Код:
inline Process::operator bool() const
{
    return pid != 0;
}
inline pid_t Process::id() const
{
    return pid;
}

Код:
int Process::action(string a)
{
system(a.c_str());
return 0;
}
  - здесь (a.c_str()) - преобразование из char в string ?
« Последнее редактирование: 16-01-2010 14:18 от ZWYHB » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 16-01-2010 15:41 » 

ZWYHB, в константных функциях компилятор не даст явно поменять значение членов класса или вызвать неконстантные методы класса
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #16 : 17-01-2010 21:46 » 

Алексей1153++, если только мемберы не были объявлены как мулаблы
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 18-01-2010 06:58 » 

lapulya, чиво ругаесси ? )) Ну, если вот так, как ты обозвал, объявили, - сами виноваты. Согласись? )
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #18 : 18-01-2010 09:06 » 

Алексей1153++, мутаблы* (описался)
Это я так... для полит корректности... (сам ни разу мутабл не использовал, насколько я помню)

ЗЫ
меня как-то по молодости на одном собеседовании спросили, что это, а я не знал. После пришел домой прочитал, нах это надо и понял, что это нах не надо )))) но запомнил так, что уже в жизни не забуду.
Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #19 : 18-01-2010 09:37 » 

lapulya, вообще бывает нужно.
Например, захват мьютекса в константном методе, мьютекс должен быть mutable
Записан

Странно всё это....
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #20 : 18-01-2010 09:51 » 

ну не делай функцию мембер константной )))... это если так писать то все функции, которые не setBUBU (т.е. призваны явно менять мембер), можно константными сделать, но это я так... бурчу...

я не говорю, что это абсолютно не нужно, но... странно мне это... короче ни разу не юзал (ну или почти не юзал... может где разочек и затерлось Улыбаюсь ) )))
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 18-01-2010 10:39 » 

lapulya, вообще бывает нужно.
Например, захват мьютекса в константном методе, мьютекс должен быть mutable
вах... вещь ) А я всегда приводил указатель к неконстантному. ))) Теперь учту
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #22 : 18-01-2010 12:13 » 

LogRus, да и потом, оберни мьютекс во что-нибудь (да так по хорошему и надо сделать) и никаких проблем...
типа так
Код:
class Mutex
{
public:
void lock() {}
};

class Process
{
Mutex * theMutex;
public:
Process() {theMutex = new Mutex();}
~Process() {delete theMutex;}
void work() const { theMutex->lock(); }
};

void main(void) 
{
Process process;
const Process * p = &process;
process.work();
p->work();
}
не помню насколько это удовлетворяет стандарту, но компилится Улыбаюсь если удовлетворяет, то так и надо писать, ну точнее я бы так написал...
Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #23 : 18-01-2010 13:37 » 

Код:
const Process * p = &process;
это запрет делать
Код:
++p;
а не запрет на модификацию памяти по адресу.
Записан

Странно всё это....
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #24 : 18-01-2010 14:32 » 

LogRus,
я ж константную функцию вызываю (в ней лочу мьютекс)!!! а это так... для порядку... хотя, для полной верности (я тут чуть налажал, но суть дела не меняется) можно и так написать

const Process * const p = &process;

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

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #25 : 18-01-2010 15:35 » 

lapulya, в любом случае в языке есть нормальное средство, для реализации требуемого функционала и строить прослойки я смысла не вижу. Улыбаюсь
Записан

Странно всё это....
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #26 : 19-01-2010 13:37 » 

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

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #27 : 20-01-2010 05:07 » 

lapulya, ничего не понял Улыбаюсь или запятых не хватает или слов Улыбаюсь
что касается линукс, то для меня ответ очевиден - возьму чужой велосипед (я так всегда делаю, зачем мне нужны проблемы с отладкой, тестированием и т.д. нового класса)
поэтому мой выбор TBB от Intel или boost
в TBB кстати отличные мьютексы (спиновые, RW, спиновые RW, обычные + всякие другие полезности) и самые лучше имхо это спиновые, а уж спиновые мьютексы я точно сам писать не буду.
Записан

Странно всё это....
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #28 : 20-01-2010 08:37 » 

LogRus, Знать на верняка будет ли переход на линукс ты сейчас вряд ли сможешь, как мне кажется...

Вообще сквозное (т.е. повсеместное, где захотел, там и использовал) использование апи платформы по всему коду без оберток, как мне кажется, не лучшее решение. Слишком тяжко будет потом менять апи (ну если придется). Поэтому я сторонник использовать в логике только свои объекты, все чужое имхо, лучше обернуть. Как оборачивать рояля не играет boost, интел или своя обертка разницы нет (лишь бы код был открыт, в противном случае мы просто одно апи на другое меняем).

В предыдущем письме я попросил привести чуть более детальный пример необходимости использование mutable, чтобы подумать настолько ли оно надо Улыбаюсь
Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #29 : 20-01-2010 09:08 » 

счётчик обращений, например, да мало ли

что касается API Улыбаюсь - не разу не пользовался Улыбаюсь
Записан

Странно всё это....
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines