URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5568
[ Назад ]

Исходное сообщение
"Взаимодействие процессов"

Отправлено drews , 13-Июл-06 17:56 
Предлогаю всем кому интересно пообсуждать тему межпроцессорных взаимодействий. Я видимо что-то не догоняю.

У меня Пять процессов. Один родительский и четыре дочерних.

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

что вы думаете об этом?


Содержание

Сообщения в этом обсуждении
"Взаимодействие процессов"
Отправлено Forth , 13-Июл-06 17:58 
>Предлогаю всем кому интересно пообсуждать тему межпроцессорных взаимодействий. Я видимо что-то не
>догоняю.
>
>У меня Пять процессов. Один родительский и четыре дочерних.
>
>так вот после того как они отработают, каждый из них имеет свое
>значение в одной переменной. моя задача их сложить. я решил, что
>правильно будет блокировать процессы оставяляя один. и так вычислить правильное значение.
>
>
>что вы думаете об этом?
А что за переменная, int?


"Взаимодействие процессов"
Отправлено drews , 13-Июл-06 18:02 
>>Предлогаю всем кому интересно пообсуждать тему межпроцессорных взаимодействий. Я видимо что-то не
>>догоняю.
>>
>>У меня Пять процессов. Один родительский и четыре дочерних.
>>
>>так вот после того как они отработают, каждый из них имеет свое
>>значение в одной переменной. моя задача их сложить. я решил, что
>>правильно будет блокировать процессы оставяляя один. и так вычислить правильное значение.
>>
>>
>>что вы думаете об этом?
>А что за переменная, int?

да. это обыкновенный счетчик.
там есть цикл с проверкой и в зависимости от того TRUE или FALSE на единицу увеличивается это значение. И это происходит в Пяти процессах. то есть в конце если попробовать распечатать эту переменную будет что-то вроде:
14
15
17
14
14


"Взаимодействие процессов"
Отправлено Forth , 13-Июл-06 18:04 
>14
>15
>17
>14
>14
Ну выходи в каждом дочернем по exit(твоя переменная). А в родителе лови по wait(3) коды выхода:)



"Взаимодействие процессов"
Отправлено drews , 13-Июл-06 18:14 
>>14
>>15
>>17
>>14
>>14
>Ну выходи в каждом дочернем по exit(твоя переменная). А в родителе лови
>по wait(3) коды выхода:)


спасибо. я попробую:)


"Взаимодействие процессов"
Отправлено drews , 14-Июл-06 13:50 
проблема в том, что мне рано завершать процесс.
А если я воспользуюсь функцией exit(), то следующая часть кода будет выполняться не корректно (а там аналогичное действие).


"Взаимодействие процессов"
Отправлено drews , 14-Июл-06 14:30 
я думаю, что лучше всего здесь исполбзовать Семафоры.
Но работают они очень запутано.

"Взаимодействие процессов"
Отправлено NuINu , 14-Июл-06 15:37 
>я думаю, что лучше всего здесь исполбзовать Семафоры.
>Но работают они очень запутано.

Ну и нафига там семафоры? кому семафорить то?
Нужно передать данные используй каналы, эти как его pipe


"Взаимодействие процессов"
Отправлено drews , 14-Июл-06 15:57 
>>я думаю, что лучше всего здесь исполбзовать Семафоры.
>>Но работают они очень запутано.
>
>Ну и нафига там семафоры? кому семафорить то?
>Нужно передать данные используй каналы, эти как его pipe

сейчас гляну pipe.
а что значит что семафорить некому?
Интересно было бы услышать чем данная реализация не подходит.


"Взаимодействие процессов"
Отправлено NuINu , 14-Июл-06 16:16 
>>>я думаю, что лучше всего здесь исполбзовать Семафоры.
>>>Но работают они очень запутано.
>>
>>Ну и нафига там семафоры? кому семафорить то?
>>Нужно передать данные используй каналы, эти как его pipe
>
>сейчас гляну pipe.
>а что значит что семафорить некому?
>Интересно было бы услышать чем данная реализация не подходит.

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


"Взаимодействие процессов"
Отправлено drews , 18-Июл-06 18:26 
Кто-нибудь разбирается в реализации семафоров?
Я прочитал множество статей, но так и не врубил.
Объясните - почему не работает такая реализация:

Выоплянется 5 процессов, значение X у каждого процесса свои
Y - общая, куда я хочу записать окончательный результат который выглядит как сумма всех X-ов


semop(sem,&g_Decrease,1);
X=X+Y;
semop(sem,&g_Increase,1);


&g_Decrease-операция понижения
&g_Increase-операция повышения
Изначально значение семафора 1 (создается с помощью semctl)


"Взаимодействие процессов"
Отправлено NuINu , 19-Июл-06 09:14 
>Кто-нибудь разбирается в реализации семафоров?
>Я прочитал множество статей, но так и не врубил.
>Объясните - почему не работает такая реализация:
>
>Выоплянется 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;


"Взаимодействие процессов"
Отправлено drews , 19-Июл-06 12:33 
ошибся в описании- я именно так и складываю:
Y=Y+X;

"Взаимодействие процессов"
Отправлено NuINu , 25-Июл-06 17:21 
>ошибся в описании- я именно так и складываю:
>Y=Y+X;

Слушай а ты вообще как Y то создал? эта вся фигня будет работать если Y создан как разделяемый объект.  shmget и shmat.

А вообще если ты хочешь ответа на первый вопрос, я тебе пример борошу ;-)) как передать по пайпам значения от дочерних процессов. Лично я не уверен что операция записи в канал неделимая так что не факт что будет всегда работать. Но на мелком примере работает. но для уверенности желательно конечно вставить семафор.


"Взаимодействие процессов"
Отправлено NuINu , 25-Июл-06 17:26 
>У меня Пять процессов. Один родительский и четыре дочерних.
>так вот после того как они отработают, каждый из них имеет свое
>значение в одной переменной. моя задача их сложить. я решил, что
>правильно будет блокировать процессы оставяляя один. и так вычислить правильное значение.

Только у меня дочерних процессов 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;
}