Предлогаю всем кому интересно пообсуждать тему межпроцессорных взаимодействий. Я видимо что-то не догоняю.У меня Пять процессов. Один родительский и четыре дочерних.
так вот после того как они отработают, каждый из них имеет свое значение в одной переменной. моя задача их сложить. я решил, что правильно будет блокировать процессы оставяляя один. и так вычислить правильное значение.
что вы думаете об этом?
>Предлогаю всем кому интересно пообсуждать тему межпроцессорных взаимодействий. Я видимо что-то не
>догоняю.
>
>У меня Пять процессов. Один родительский и четыре дочерних.
>
>так вот после того как они отработают, каждый из них имеет свое
>значение в одной переменной. моя задача их сложить. я решил, что
>правильно будет блокировать процессы оставяляя один. и так вычислить правильное значение.
>
>
>что вы думаете об этом?
А что за переменная, int?
>>Предлогаю всем кому интересно пообсуждать тему межпроцессорных взаимодействий. Я видимо что-то не
>>догоняю.
>>
>>У меня Пять процессов. Один родительский и четыре дочерних.
>>
>>так вот после того как они отработают, каждый из них имеет свое
>>значение в одной переменной. моя задача их сложить. я решил, что
>>правильно будет блокировать процессы оставяляя один. и так вычислить правильное значение.
>>
>>
>>что вы думаете об этом?
>А что за переменная, int?да. это обыкновенный счетчик.
там есть цикл с проверкой и в зависимости от того TRUE или FALSE на единицу увеличивается это значение. И это происходит в Пяти процессах. то есть в конце если попробовать распечатать эту переменную будет что-то вроде:
14
15
17
14
14
>14
>15
>17
>14
>14
Ну выходи в каждом дочернем по exit(твоя переменная). А в родителе лови по wait(3) коды выхода:)
>>14
>>15
>>17
>>14
>>14
>Ну выходи в каждом дочернем по exit(твоя переменная). А в родителе лови
>по wait(3) коды выхода:)
спасибо. я попробую:)
проблема в том, что мне рано завершать процесс.
А если я воспользуюсь функцией exit(), то следующая часть кода будет выполняться не корректно (а там аналогичное действие).
я думаю, что лучше всего здесь исполбзовать Семафоры.
Но работают они очень запутано.
>я думаю, что лучше всего здесь исполбзовать Семафоры.
>Но работают они очень запутано.Ну и нафига там семафоры? кому семафорить то?
Нужно передать данные используй каналы, эти как его pipe
>>я думаю, что лучше всего здесь исполбзовать Семафоры.
>>Но работают они очень запутано.
>
>Ну и нафига там семафоры? кому семафорить то?
>Нужно передать данные используй каналы, эти как его pipeсейчас гляну pipe.
а что значит что семафорить некому?
Интересно было бы услышать чем данная реализация не подходит.
>>>я думаю, что лучше всего здесь исполбзовать Семафоры.
>>>Но работают они очень запутано.
>>
>>Ну и нафига там семафоры? кому семафорить то?
>>Нужно передать данные используй каналы, эти как его pipe
>
>сейчас гляну pipe.
>а что значит что семафорить некому?
>Интересно было бы услышать чем данная реализация не подходит.ты знаешь я пожалуй не прав, придеться семафоры ставить ;-)))
и при работе с пайпами, иначе они(5 процессов) туда кашу запишут.
а соотвественно головной процесс ее будет пытаться разобрать.
звиняюсь виноват
Кто-нибудь разбирается в реализации семафоров?
Я прочитал множество статей, но так и не врубил.
Объясните - почему не работает такая реализация:Выоплянется 5 процессов, значение X у каждого процесса свои
Y - общая, куда я хочу записать окончательный результат который выглядит как сумма всех X-ов
semop(sem,&g_Decrease,1);
X=X+Y;
semop(sem,&g_Increase,1);
&g_Decrease-операция понижения
&g_Increase-операция повышения
Изначально значение семафора 1 (создается с помощью semctl)
>Кто-нибудь разбирается в реализации семафоров?
>Я прочитал множество статей, но так и не врубил.
>Объясните - почему не работает такая реализация:
>
>Выоплянется 5 процессов, значение X у каждого процесса свои
>Y - общая, куда я хочу записать окончательный результат который выглядит как
>сумма всех X-ов
>
>
>semop(sem,&g_Decrease,1);
>X=X+Y;
>semop(sem,&g_Increase,1);
>
>
>&g_Decrease-операция понижения
>&g_Increase-операция повышения
>Изначально значение семафора 1 (создается с помощью semctl)ну я бы сказал потому что надо складывать так:
Y=Y+X;
ошибся в описании- я именно так и складываю:
Y=Y+X;
>ошибся в описании- я именно так и складываю:
>Y=Y+X;Слушай а ты вообще как Y то создал? эта вся фигня будет работать если Y создан как разделяемый объект. shmget и shmat.
А вообще если ты хочешь ответа на первый вопрос, я тебе пример борошу ;-)) как передать по пайпам значения от дочерних процессов. Лично я не уверен что операция записи в канал неделимая так что не факт что будет всегда работать. Но на мелком примере работает. но для уверенности желательно конечно вставить семафор.
>У меня Пять процессов. Один родительский и четыре дочерних.
>так вот после того как они отработают, каждый из них имеет свое
>значение в одной переменной. моя задача их сложить. я решил, что
>правильно будет блокировать процессы оставяляя один. и так вычислить правильное значение.Только у меня дочерних процессов 5, а так подходит.
там макросы - их можно выкинуть.
сложение в главном модуле легко приделать ;-))
/* Демонстрация запуска нескольких процессов
создадим двунаправленный канал и попробуем
через него дочерние процессы передадут в родительский некие данные
а он их попытается прочитать и распечатать.
*/
#include "defs.h"typedef struct ps_my {
int pid;
int val;
bool IsExit;
} ps_my_stru;typedef struct pipe_my {
int pid;
int val;
} pipe_my_data;#define MAX_CHILD 5
void init_psarr(void);
ps_my_stru ps_info[MAX_CHILD];
int pfd[2]; /*дескрипторы файлов pipe*/void init_psarr(void) {
ps_info[0].val = 10;
ps_info[1].val = 100;
ps_info[2].val = 1000;
ps_info[3].val = 50;
ps_info[4].val = 500;for(int i = 0; i < MAX_CHILD; i++) {
ps_info[i].IsExit = false;
}
}void child_work(int ind) {
pipe_my_data d;
d.pid = getpid();
d.val = ps_info[ind].val;
printf("Работает Дочерний процесс PID = %d, ind = %d, val = %d\n", d.pid, ind, d.val);
/*Пишем 1 раз в канал*/
write(pfd[1], &d, sizeof(d));
}int FindWorked(void) {
for(int i = 0; i < MAX_CHILD; i++) {
if(ps_info[i].IsExit == false)
return 1; /*нашли работающий процесс*/
}
return 0; /*нет работающих процессов*/
}int MakeClose(int pid) {
for(int i = 0; i < MAX_CHILD; i++) {
if(ps_info[i].pid == pid) {
ps_info[i].IsExit = true; /*пометим процесс как завершенный*/
return i;
}
}
return -1; /*не нашли этот процесс(в принципе прога должна в этом случае зависать)*/
}int CalculateWork(void) {
int ret = 0;
for(int i = 0; i < MAX_CHILD; i++) {
if(ps_info[i].IsExit == false) {
ret++;
}
}
return ret;
}void parent_work(void) {
int pid, ind, i;
int CountWork = CalculateWork();
int FailFind = 0;
printf("Породили %d процессов\n", CountWork);
/*Читаем 5 раз из канала и печатем разультат*/
pipe_my_data d;
for(i = 0; i < CountWork; i++) {
read(pfd[0], &d, sizeof(d));
printf("Получили от процесса %d значение = %d\n", d.pid, d.val);
}
printf("Ждем их завершения\n");
do {
pid = waitpid(-1, NULL, 0);
ind = MakeClose(pid);
if(ind >= 0) {
printf("Завершился процесс pid = %d, ind = %d\n", pid, ind);
} else {
printf("Завершился процесс pid = %d, Но его нет в таблице процессов!!!\n", pid);
FailFind++;
}
CountWork--;
if(CountWork < FailFind) {
printf("Не вижу смысла продолжать ждать потомка, возможно их больше нет!\n");
break;
}
} while(FindWorked());
}
void forktest(void) {
init_psarr();
int pid;
int is_child = 0;
printf("Начало теста\n");
ec_neg1( pipe(pfd) )
printf("Открыли канал\n");
int i;
for(i = 0; i < MAX_CHILD; i++) {
switch(pid = fork()) {
case -1: /*Предок ошибка возможно процесс на запустился пометим его как завершившийся!!!*/
ps_info[i].IsExit = true;
case 0: /*Потомок*/
is_child = 1;
break;
default: /*основной процесс*/
ps_info[i].pid = pid;
}
if(is_child) break;
}
if(is_child) {
child_work(i);
} else {
parent_work();
}
/* printf("Возвращенное значение PID = %d\n", pid);*/
return;
EC_CLEANUP_BGN
EC_FLUSH("forktest")
if(is_child == 1)
exit(EXIT_FAILURE);
EC_CLEANUP_END
}
int main(int argc, char *argv[]) {
forktest();
return 0;
}