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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сообщения между процессами, сообщения повторяются 
:(
    Опции темы
5pY
Дата 24.5.2011, 02:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



В программе идёт обмен сообщениями между процессом-предком и двумя дочерними. Почему-то сообщения от второго дочернего процесса повторяются, хотя код такой же как и в первом(только типы сообщений разные естественно). Обработка сообщений предком тоже одинакова.
Вот коды:
Код

Предок:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#define pr1_END 11
#define pr1_STOP 22
#define pr1_RUN 33
#define pr2_END 44
#define pr2_STOP 55
#define pr2_RUN 66
int main(int argc,char **argv)
{
    pid_t a;
    pid_t b;
    pid_t pid2,pid1; 
    int status,ret,pr1=0,pr2=0;
    int msqid; /* IPC дескриптор для очереди сообщений */
    bool pr1_exit=false,pr2_exit=false;
    char pathname[] = "lab6.c"; /* Имя файла, использующееся для генерации ключа. Файл с таким именем должен существовать в текущей директории */
     key_t key; /* IPC ключ */ 
     int i,len,maxlen; /* Счетчик цикла и длина информативной части сообщения */
     /* Ниже следует пользовательская структура для сообщения */
     struct newmsgbuf
    {
        long mtype;
        int mtext[1];
    }buf;
     /* Генерируем IPC ключ из имени файла lab6.c в текущей директории и номера экземпляра очереди сообщений 0. */
printf("start!");     
if((key = ftok(pathname,13)) < 0){
         printf("Ошибка! Ключ не сгенерирован!");
         exit(-1);
     }
     /* Пытаемся получить доступ по ключу к очереди сообщений,если она существует, или создать ее, с правами доступа read & write для всех пользователей */ 
     
    msqid = msgget(key, 0666 | IPC_CREAT);
        a = fork();
    b = fork();
    if(a==0)
    {
        ret=execl("./nasl1.out","nasl1",NULL);
    }
    if(b==0)
    {
        ret=execl("./nasl2.out","nasl2",NULL);
    }

        while(1)
        { 
             maxlen = 128;
            if(pr2_exit==false)
            {
            len = msgrcv(msqid,&buf, maxlen, pr2_STOP, 0);
             if (buf.mtype == pr2_STOP)
                {
                buf.mtype = pr2_RUN;
                len = 0;
                 msgsnd(msqid, &buf,len, 0);
                len = msgrcv(msqid,&buf, maxlen, 2, 0);
                if (buf.mtype == 2){
                    printf("сообщение №%d от процесса №%ld\n",buf.mtext[0],buf.mtype);
                    pr2=pr2+1;
                 }
                if(pr2==15)len = msgrcv(msqid,&buf, maxlen, pr2_END, 0);
                 if (buf.mtype == pr2_END){
                    pr2_exit=true;
                     }
                }
             }
            sleep(1);
            if(pr1_exit==false)
            {
            
            len = msgrcv(msqid,&buf, maxlen, pr1_STOP, 0);
             if (buf.mtype == pr1_STOP)
                {
                buf.mtype = pr1_RUN;
                len = 0;
                 msgsnd(msqid, &buf,len, 0);
                len = msgrcv(msqid,&buf, maxlen, 1, 0);
                if (buf.mtype == 1){
                    printf("сообщение №%d от процесса №%ld\n",buf.mtext[0],buf.mtype);
                    pr1=pr1+1;
                 }
                if(pr1==15)len = msgrcv(msqid,&buf, maxlen, pr1_END, 0);
                 if (buf.mtype == pr1_END){
                    pr1_exit=true;
                     }
                }
             }
        sleep(1);
        
            if (pr1_exit==true && pr2_exit==true){
            msgctl(msqid, IPC_RMID, NULL);
             exit(0);
         }
    }
}
    


Дочерний 1(его сообщения дублируются):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>

#define pr1_END 11
#define pr1_STOP 22
#define pr1_RUN 33

int main()
{
    
    int msqid; /* IPC дескриптор для очереди сообщений */
char pathname[] = "lab6.c"; /* Имя файла, использующееся для генерации ключа. Файл с таким именем должен существовать в текущей директории */
    key_t key; /* IPC ключ */ 
    int i,len,maxlen; /* Счетчик цикла и длина информативной части сообщения */
    /* Ниже следует пользовательская структура для сообщения */
    struct newmsgbuf
    { 
        long mtype;
        int mtext[1]; 
    } buf;
    /* Генерируем IPC ключ из имени файла lab6.c в текущей директории и номера экземпляра очереди сообщений 0. */
    if((key = ftok(pathname,13)) < 0){
        printf("Наследник 1, ошибка генерации ключа!");
        exit(-1);
    }
    /* Пытаемся получить доступ по ключу к очереди сообщений,если она существует, или создать ее, с правами доступа read & write для всех пользователей */ 
    msqid = msgget(key, 0666 | IPC_CREAT);
    /* Посылаем в цикле 100 сообщений с типом 1 в очередь сообщений, идентифицируемую msqid.*/
    for (i = 1; i <= 15; i++){
    buf.mtype = pr1_STOP;
     len = 0;
     msgsnd(msqid,&buf,len, 0);
    maxlen = 128;
        len = msgrcv(msqid, &buf, maxlen, pr1_RUN, 0);
        if (buf.mtype == pr1_RUN){
        buf.mtype = 1;
        buf.mtext[0]=i;
         msgsnd(msqid, &buf,sizeof(buf.mtext), 0);
         }
       
    }
    /* Отсылаем сообщение, которое заставит получающий процесс
    прекратить работу, с типом D1_END и длиной 0 */ 
    buf.mtype = pr1_END;
    len = 0;
    msgsnd(msqid,&buf,len, 0);
    exit(0);
}


Дочерний 2(работает как положено):


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>

#define pr2_END 44
#define pr2_STOP 55
#define pr2_RUN 66

int main()
{
    
    int msqid; /* IPC дескриптор для очереди сообщений */
char pathname[] = "lab6.c"; /* Имя файла, использующееся для генерации ключа. Файл с таким именем должен существовать в текущей директории */
    key_t key; /* IPC ключ */ 
    int i,len,maxlen; /* Счетчик цикла и длина информативной части сообщения */
    /* Ниже следует пользовательская структура для сообщения */
    struct newmsgbuf
    { 
        long mtype;
        int mtext[1]; 
    } buf;
    /* Генерируем IPC ключ из имени файла lab6.c в текущей директории и номера экземпляра очереди сообщений 0. */
    if((key = ftok(pathname,13)) < 0){
        printf("Наследник 2, ошибка генерации ключа!");
        exit(-1);
    }
    /* Пытаемся получить доступ по ключу к очереди сообщений,если она существует, или создать ее, с правами доступа read & write для всех пользователей */ 
    msqid = msgget(key, 0666 | IPC_CREAT);
    /* Посылаем в цикле 100 сообщений с типом 1 в очередь сообщений, идентифицируемую msqid.*/
    for (i = 1; i <= 15; i++){
    buf.mtype = pr2_STOP;
     len = 0;
     msgsnd(msqid,&buf,len, 0);
    maxlen = 128;
        len = msgrcv(msqid, &buf, maxlen, pr2_RUN, 0);
        if (buf.mtype == pr2_RUN){
        buf.mtype = 2;
        buf.mtext[0]=i;
         msgsnd(msqid, &buf,sizeof(buf.mtext), 0);
         }
        
    }
    /* Отсылаем сообщение, которое заставит получающий процесс
    прекратить работу, с типом D1_END и длиной 0 */ 
    buf.mtype = pr2_END;
    len = 0;
    msgsnd(msqid,&buf,len, 0);
    exit(0);
}




PM MAIL   Вверх
svlary
Дата 24.5.2011, 05:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Вот эта конструкция ошибочна :

Код

    a = fork();
    b = fork();


На самом деле она означает вот что :
  • Родительский процесс порождает дочерний
  • Потом И родительский И дочерний ОБА порождают еще по одному процессу.

Т.е., в итоге, у Вас получается не три, а четыре процесса smile
PM MAIL   Вверх
5pY
Дата 24.5.2011, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



А если сделать так:
Код

a=fork();
if (a>0) b=fork;


будет работать? Просто нет возможности проверить
PM MAIL   Вверх
MAKCim
Дата 24.5.2011, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



5pY
проще сесть, почитать мануал и разобраться
на полном серьезе


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
svlary
Дата 25.5.2011, 05:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(MAKCim @  24.5.2011,  21:32 Найти цитируемый пост)
почитать мануал и разобраться

  Вот здесь :
Процессы. Основные понятия.
очень хорошо и подробно все описано.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

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

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


 




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


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

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