ZWYHB
Участник
Offline
|
|
« : 15-01-2010 07:28 » |
|
Необходимо реализовать функцию запуска и параллельного выполнения нескольких программ. Задаётся количество выполняемых программ и набор их имён (пути к исполняемым образам). Исходный процесс завершается сразу после их порождения. Написать тестовую программу для проверки работоспособности разработанной функции. вот что получилось: main.cpp #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 #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 #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; } Всё работает Но значительную часть этого взял из методички - вроде понимаю что здесь происходит - но препод придирается Не могли бы рассписать - что здесь к чему? Особенно интересуют это : 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 и 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
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #1 : 15-01-2010 08:36 » |
|
А к чему именно препод "придирается", и что тебе нужно объяснить (код тут самый наиочевиднейший)?
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
ZWYHB
Участник
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 от Вад »
|
Записан
|
|
|
|
Вад
|
|
« Ответ #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
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #4 : 15-01-2010 11:22 » |
|
Интересно, как можно написать лабу на языке программирования "продолжение которого сам не знаешь" (с) х/ф "Кин-дза-дза"...
В общем, проблема не в процессах и не в лабе, а в незнании языка программирования.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
ZWYHB
Участник
Offline
|
|
« Ответ #5 : 15-01-2010 13:34 » |
|
В общем, проблема не в процессах и не в лабе, а в незнании языка программирования. Я только учусь!! Вад, ты не мог бы поподробнее написать про вектор процессов?
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #6 : 15-01-2010 13:47 » |
|
А что про него подробнее писать? Контейнер из стандартной библиотеки STL, замена обычным динамическим массивам. Построен в виде шаблона - то есть, позволяет адаптировать шаблонную реализацию для хранения элементов любого типа.
Вообще, это настолько естественная часть C++ сейчас, что даже удивительно, почему в методичке он у тебя есть, и при этом требуется объяснять, что это.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #7 : 15-01-2010 14:07 » |
|
Тогда нужно объяснить, что такое конструктор. Что такое вектор и т.д.
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
ZWYHB
Участник
Offline
|
|
« Ответ #8 : 15-01-2010 14:20 » |
|
Ну вот накинулись! Знаю я - что такое конструкторы, деструкторы и прочее. Контейнеры подзабылись.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #9 : 15-01-2010 14:26 » |
|
Накинулись? Пытаемся понять, что ты знаешь.
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #10 : 16-01-2010 01:43 » |
|
Что то я не пойму, в чем собственно вопрос...
|
|
|
Записан
|
С уважением Lapulya
|
|
|
ZWYHB
Участник
Offline
|
|
« Ответ #11 : 16-01-2010 08:13 » |
|
Вот ещё маленький вопрос case 0: pid = getpid(); exit(action(a)); } return true;
Вот здесь - я правильно понимаю - в случае если мы в потомке - получаем идентификатор процесса, выполняем action и выходим? pid = getpid(); - что конкретно означает?
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #12 : 16-01-2010 09:06 » |
|
У тебя Process хранит pid для запускаемого процесса. fork возвращает 0 в экземпляр дочернего процесса. И функция getpid вызывается, чтобы узнать pid текущего процесса.
|
|
|
Записан
|
|
|
|
ZWYHB
Участник
Offline
|
|
« Ответ #13 : 16-01-2010 09:18 » |
|
спасибо!
|
|
|
Записан
|
|
|
|
ZWYHB
Участник
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 »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 16-01-2010 15:41 » |
|
ZWYHB, в константных функциях компилятор не даст явно поменять значение членов класса или вызвать неконстантные методы класса
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #16 : 17-01-2010 21:46 » |
|
Алексей1153++, если только мемберы не были объявлены как мулаблы
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 18-01-2010 06:58 » |
|
lapulya, чиво ругаесси ? )) Ну, если вот так, как ты обозвал, объявили, - сами виноваты. Согласись? )
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #18 : 18-01-2010 09:06 » |
|
Алексей1153++, мутаблы* (описался) Это я так... для полит корректности... (сам ни разу мутабл не использовал, насколько я помню)
ЗЫ меня как-то по молодости на одном собеседовании спросили, что это, а я не знал. После пришел домой прочитал, нах это надо и понял, что это нах не надо )))) но запомнил так, что уже в жизни не забуду.
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Антон (LogRus)
|
|
« Ответ #19 : 18-01-2010 09:37 » |
|
lapulya, вообще бывает нужно. Например, захват мьютекса в константном методе, мьютекс должен быть mutable
|
|
|
Записан
|
Странно всё это....
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #20 : 18-01-2010 09:51 » |
|
ну не делай функцию мембер константной )))... это если так писать то все функции, которые не setBUBU (т.е. призваны явно менять мембер), можно константными сделать, но это я так... бурчу... я не говорю, что это абсолютно не нужно, но... странно мне это... короче ни разу не юзал (ну или почти не юзал... может где разочек и затерлось ) )))
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #21 : 18-01-2010 10:39 » |
|
lapulya, вообще бывает нужно. Например, захват мьютекса в константном методе, мьютекс должен быть mutable
вах... вещь ) А я всегда приводил указатель к неконстантному. ))) Теперь учту
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
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)
|
|
« Ответ #23 : 18-01-2010 13:37 » |
|
const Process * p = &process;
это запрет делать а не запрет на модификацию памяти по адресу.
|
|
|
Записан
|
Странно всё это....
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #24 : 18-01-2010 14:32 » |
|
LogRus, я ж константную функцию вызываю (в ней лочу мьютекс)!!! а это так... для порядку... хотя, для полной верности (я тут чуть налажал, но суть дела не меняется) можно и так написать
const Process * const p = &process;
тут ваще все константное (хотя вызова константной функции было уже достаточно, чтобы продемонстрировать мою мысль).
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Антон (LogRus)
|
|
« Ответ #25 : 18-01-2010 15:35 » |
|
lapulya, в любом случае в языке есть нормальное средство, для реализации требуемого функционала и строить прослойки я смысла не вижу.
|
|
|
Записан
|
Странно всё это....
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #26 : 19-01-2010 13:37 » |
|
в принципе согласен, но тут бы я точно обернул (не равен час на линукс переходить надо будет). Кстати, если а можно ли пример где это надо, потому как если юзается мьютекс, так он видимо используется за пределами класса (иначе это была бы критическая секция, хотя и секцию можно передать), причем как часть реализации а не логики... хммм я бы оборачивал подобные куски (речь не о синхронизации потоков, а вообще)... но для наглядности лучше приведи пример или опиши пример... хочется поразмыслить...
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Антон (LogRus)
|
|
« Ответ #27 : 20-01-2010 05:07 » |
|
lapulya, ничего не понял или запятых не хватает или слов что касается линукс, то для меня ответ очевиден - возьму чужой велосипед (я так всегда делаю, зачем мне нужны проблемы с отладкой, тестированием и т.д. нового класса) поэтому мой выбор TBB от Intel или boost в TBB кстати отличные мьютексы (спиновые, RW, спиновые RW, обычные + всякие другие полезности) и самые лучше имхо это спиновые, а уж спиновые мьютексы я точно сам писать не буду.
|
|
|
Записан
|
Странно всё это....
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #28 : 20-01-2010 08:37 » |
|
LogRus, Знать на верняка будет ли переход на линукс ты сейчас вряд ли сможешь, как мне кажется... Вообще сквозное (т.е. повсеместное, где захотел, там и использовал) использование апи платформы по всему коду без оберток, как мне кажется, не лучшее решение. Слишком тяжко будет потом менять апи (ну если придется). Поэтому я сторонник использовать в логике только свои объекты, все чужое имхо, лучше обернуть. Как оборачивать рояля не играет boost, интел или своя обертка разницы нет (лишь бы код был открыт, в противном случае мы просто одно апи на другое меняем). В предыдущем письме я попросил привести чуть более детальный пример необходимости использование mutable, чтобы подумать настолько ли оно надо
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Антон (LogRus)
|
|
« Ответ #29 : 20-01-2010 09:08 » |
|
счётчик обращений, например, да мало ли что касается API - не разу не пользовался
|
|
|
Записан
|
Странно всё это....
|
|
|
|