LINUX.ORG.RU

Очередь сообщений


0

0

На си++ создаю новую очередь сообщений с помощью msgget, затем создаю потомка программы при помощи fork, из потомка шлю основной программе с помощью msgsnd очередь, в программе принимаю ее msgrcv'ом, меняю принятое сообщение, но после этого при попытке обратно отослать измененную очередь сообщений от родителя к потомку msgrcv возвращает -1. В чем проблема?


В общем задание заключается в следующем: Написать программу, создающую 2 процесса – родителя и потомка. Потомок читает текст из файла (имя файла передаётся программе в качестве параметра) и построчно пересылает его родителю. Родитель заменяет во всех строках слово «3» на «three» и построчно отправляет результат потомку. Потомок сохраняет результат в файл с именем, переданным программе в качестве параметра, с суффиксом «.result» и завершает работу. Родитель ждёт завершения потомка и завершает работу сам. Все это используя очередь сообщения и сигналы для синхронизации

Все почти работает, но когда родитель отсылает потомку измененный текст, чтобы его напечатать в файл, в файл печатается неизмененный текст с 3 повсюду вместо three

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

char s[100];

struct msgbufr
  {
    long int mtype;
    char mtext[100];
  };

void catch_alarm(int sig)
{
    printf("done\n");
}

int main(int argc, char** argv)
{
    
    setvbuf(stdout, (char*) NULL,_IONBF,0);
    pid_t pid;
    int msqid,i;
    int msgflg = IPC_CREAT | 0666;
    key_t key,key2;
    msgbufr sbuf, rbuf;
    size_t buf_length;
    struct msqid_ds qstatus;
    key=1;
    key2=2;
//    if (argc!=2)
//    {
//        printf("Wrong parameters\n");
//        exit (1);
//    }
    if ((msqid = msgget(key, msgflg )) < 0)
    {
        printf("Can't create message queue\n");
        exit (1);
    }
    sbuf.mtype=1;
    rbuf.mtype=2;
    pid=fork();
    switch (pid)
    {
        case -1:
            printf("Can't create process\n");
            msgctl(msqid,IPC_RMID,&qstatus);
            return 1;
        case 0:
        {            
            FILE* f=fopen("/home/sabikftw/file4","r");
            if (f==NULL)
            {
                printf("Wrong file\n");
                msgctl(msqid,IPC_RMID,&qstatus);
                exit(1);
            }
            char str[100];
            char c;
            i=0;
            while ((c=getc(f))!=EOF)
            {
                str[i]=c;
                i++;
            }
            str[i]='\0';         
            printf("\n");
            fclose(f);
            printf("%d\n",i);
            if (i>=100)
            {
                printf("Incorrect string\n");
                msgctl(msqid,IPC_RMID,&qstatus);
                exit(1);
            }
            i=0;
            while (str[i]!='\0')
            {
                sbuf.mtext[i]=str[i];
                i++;
            }
            sbuf.mtext[i]='\0';
            buf_length=strlen(sbuf.mtext) + 1;
            if (msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT) < 0)
            {
                printf("Error writing into queue\n");
                msgctl(msqid,IPC_RMID,&qstatus);
                exit(1);
            }
            printf(sbuf.mtext);
            printf("asdaf\n");
            usleep(400);
            kill(getppid(),SIGALRM);
            signal(SIGALRM,&catch_alarm);
            pause();
            if (msgrcv(msqid, &sbuf, 100, 1, 0) < 0)
            {
                printf("Error reading from queue\n");
                msgctl(msqid,IPC_RMID,&qstatus);
                exit(1);
            }
            printf("rrr");
            char path[sizeof("/home/sabikftw/file4")+12];
            for (int j=0;j<=sizeof("/home/sabikftw/file4")-2;j++)
            {
                 path[j]="/home/sabikftw/file4"[j];
            }
            path[sizeof("/home/sabikftw/file4")-1]='.';
            path[sizeof("/home/sabikftw/file4")]='r';
            path[sizeof("/home/sabikftw/file4")+1]='e';
            path[sizeof("/home/sabikftw/file4")+2]='s';
            path[sizeof("/home/sabikftw/file4")+3]='u';
            path[sizeof("/home/sabikftw/file4")+4]='l';
            path[sizeof("/home/sabikftw/file4")+5]='t';
            path[sizeof("/home/sabikftw/file4")+6]='\0';
            printf(path);
            printf("\n");
            printf("%s\n", sbuf.mtext);
            FILE* out=fopen(path,"w+");
            if (out==NULL)
            {
                printf("Error in writing to file\n");
                msgctl(msqid,IPC_RMID,&qstatus);
                exit(1);
            }
            fprintf(out,"%s",sbuf.mtext);
            fclose(out);
            usleep(400);
            kill(getppid(),SIGALRM);
            printf("asdasdasd\n");
            break;
        }
        default:
            signal(SIGALRM, &catch_alarm);
            int time1=sleep(5);
            if (time1==0)
            {
                msgctl(msqid,IPC_RMID,&qstatus);
                kill(pid,SIGINT);
                return 0;
            }
            printf("yes!\n");
            if (msgrcv(msqid, &sbuf, 100, 1, 0) < 0)
            {
                printf("Error reading from queue\n");
                msgctl(msqid,IPC_RMID,&qstatus);
                kill(pid,SIGKILL);
                exit(1);
            }
            printf("%s\n", sbuf.mtext);
            int i=0;
            while (sbuf.mtext[i]!='\0')
            {
                s[i]=sbuf.mtext[i];
                i++;
            }
            s[i]='\0';
            i=0;
            while(s[i]!='\0')
            {
                if (s[i]=='3')
                {
                    for (int j=sizeof(s);j-4>i;j--)
                    {
                        s[j]=s[j-4];
                        s[j-4]='\0';
                    }
                    s[i]='t';
                    if (((i+1)!=sizeof(s)) && (s[i+1]!='\n'))
                        s[i+1]='h';
                    if (((i+2)!=sizeof(s)) && (s[i+2]!='\n'))
                        s[i+2]='r';
                    if (((i+3)!=sizeof(s)) && (s[i+3]!='\n'))
                        s[i+3]='e';
                    if (((i+4)!=sizeof(s)) && (s[i+4]!='\n'))
                        s[i+4]='e';
                }
                i++;
            }
            i=0;
            while (s[i]!='\0')
            {
                sbuf.mtext[i]=s[i];
                i++;
            }
            int n;
            printf("%s\n", sbuf.mtext);
            if ((n = msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT)) < 0)
            {
                printf("Error writing into queue1\n");
                msgctl(msqid,IPC_RMID,&qstatus);
                kill(pid,SIGKILL);
                exit(1);
            }
            usleep(400);
            kill(pid,SIGALRM);
            signal(SIGALRM,&catch_alarm);
            int time2=sleep(5);
            if (time2==0)
            {
                msgctl(msqid,IPC_RMID,&qstatus);
                kill(pid,SIGINT);
                return 0;
            }
            msgctl(msqid,IPC_RMID,&qstatus);
            kill(pid,SIGINT);
            exit (0);
	    break;
        }
    return 1;
}
Sabik ()
Ответ на: комментарий от Sabik

это что, индус писал?

что касается определения причин - man perror, man strerror, man errno. и расставить их в нужных местах вместо безликих printf(«Error writing into queue1\n»);

ananas ★★★★★ ()
Ответ на: комментарий от Sabik

Индусокод. Почему нет сигфолтов --- загадка. sizeof это кол-во байт, нельзя s[sizeof(s)]. Почему 4, вроде three это 5 букв?.

for (int j=sizeof(s);j-4>i;j--) 
{ 
   s[j]=s[j-4]; 
   s[j-4]='\0'; 
} 

Где определяется buf_length в «родителе»?

Прочитайте про функции работы со строками, допустим strcpy(), strcat(), а то этот ужос «path[sizeof(»/home/sabikftw/file4")+1]='e';" на ночь смотреть...

mky ★★★★★ ()
Ответ на: комментарий от Sabik

>...2 процесса...

Родитель заменяет во всех строках слово «3» на «three» и построчно отправляет результат потомку

Все это используя очередь сообщения и сигналы для синхронизации

Эх.... Зачем решать задачу именно в таком виде. Сферическое межпроцессорное взаимодействие в вакууме? Так и подмывает сказать что-то вроде - «А что?. Зачетная неделя уже началась?» или «Когда же вас наконец-то всех отчислят?»

pathfinder ★★★★ ()

прозреваю, что fork разделяет на обоиз одно адресное пространство и какой-нить буфер один на двоих или что-то в этом духе, короче мозг в помощь

dimon555 ★★★★★ ()

какая-то неудачная копипаста чужой лабы?

почему везде используется sbuf, а rbuf только объявляется и что-то меняется?

dimon555 ★★★★★ ()

проблема в ДНК

anonymous ()

why so msgget?

А не проще pipe(2) + fork(2) + dup2 + read/write?

linuxfan ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.