Find the answer to your Linux question:
Results 1 to 5 of 5
Hi, I am new to systems programming.. I am writing a code which communicates between 2 processes created by fork() statement. Parent reads a file and write the data into ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Sep 2010
    Posts
    2

    signal communication between the processes


    Hi,

    I am new to systems programming.. I am writing a code which communicates between 2 processes created by fork() statement. Parent reads a file and write the data into a shared memory and sends a signal to the child. The child then receives a signal from the parent to start reading. After finishing the read operation the child sends a signal to the parent asking it to resume its action.

    Some things are going wrong in my code.
    1. segmentation error in memcpy() statement.
    2. terminal hangs after running the code.
    3. Synchronization problem between processes..

    I would really appreciate if any of you could help me.
    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <wait.h>
    #include <unistd.h>
    #include <signal.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/wait.h>
    
    void  sharedmem(char *buffer, int *count)
    {
        int shmem_id, shmem_id1;
        key_t key;
        int size, flag;
        key = 4455;size = 1024;flag = 1023;
    
        /* First, create a shared memory segment */
        shmem_id = shmget (key, size, flag);
        shmem_id1=shmget(key,sizeof(int),flag);
        if (shmem_id == -1)
        {
            perror ("shmget failed");
            exit (1);
        }
        buffer = (char *) shmat (shmem_id, (void *) NULL, 1023);
        count= (int *)shmat( shmem_id1,(void *) NULL,1023);
        if (buffer == (void *) -1)
        {
            perror ("shmat failed");
            exit (2);
        }
        /* Done with the program, so detach the shared segment and terminate */
    //    printf("%s",buffer);
        shmdt ( (void *)  buffer);
    }
    void handler(int a){
      printf("\ncaught signal %d\n", a);
    }
    
    void main(int arvc,char *argv[])
    {
        int waiting;
        char *buffer;
        static int cnt = 0;
        int *count,pid;
        int stat,count_main=0;
        char *buff= (char*)malloc(1024);
        FILE *fr;
        sigset_t  zeromask;
        struct sigaction  action, old_action;
    
    printf("SIGUSR1=%d SIGUSR2=%d", SIGUSR1, SIGUSR2);
        /* Block all signals when executing handler */
        sigfillset(&action.sa_mask);
        action.sa_handler = handler;
        action.sa_flags = 0;
        sigaction(SIGUSR2,&action,&old_action);
        sigaction(SIGUSR1,&action,&old_action);
        count = &cnt;
        sharedmem(buffer, count);
        pid=fork();
        if (pid)
        {
        sigset_t new_mask;
        sigemptyset(&new_mask);
        sigaddset(&new_mask,SIGUSR2);
        fr = fopen(argv[1], "r");
    
        do
        {
        count_main = fread ( buff, 1, 1024, fr);
        printf("\n%s",buff);
        //printf("count_main %d \n",count_main);
        /* initialize the new signal mask */
        while(*count != 0)
           {
               sigsuspend(&new_mask);  //Wait for SIGUSR2
            }
        memcpy(buffer, buff, count_main);
        //printf("%s", buffer);
        *count = count_main;
        printf("\n count in parent %d \n",*count);
        sleep(1);
        kill(pid,SIGUSR1);
        //printf("\n EOF IS %d %d",EOF, buff[count_main]);
    //    if(count_main<1024)
                                      //    if(count_main<1024)
    //break;
        }while (feof(fr)==0);
        fclose(fr);
       //sigset_t newmask1;
        sigfillset(&new_mask);
        sigdelset(&new_mask,SIGUSR2);
         while(*count!=0)
            {
                    sigsuspend(&new_mask);
            }
           printf("\n parent process resumed");
            count=-1;
            kill(pid,SIGUSR1);
        }
        else
    {
        FILE * fo=fopen("output","w");
        sigset_t new_mask1;
        sigfillset(&new_mask1);
        sigdelset(&new_mask1,SIGUSR1);
       printf("\nparent process id= %d",getppid());// while(*count!=-1)
        {
         while(*count==0)
           {
           sigsuspend(&new_mask1);  //Wait for SIGUSR1}
          }
    printf("\nchild process resumed");
        if(1){
           fwrite(buffer,1,*count,fo);
           *count=0;
           kill(getppid(),SIGUSR2);
          }
    
        }
    }
    wait(&waiting);
    }
    Thanks,
    Abhishek

  2. #2
    Linux Newbie
    Join Date
    Apr 2007
    Posts
    119
    Code:
    void  sharedmem(char *buffer, int *count)
    {
        int shmem_id, shmem_id1;
        key_t key;
        int size, flag;
        key = 4455;size = 1024;flag = 1023;
    
        /* First, create a shared memory segment */
        shmem_id = shmget (key, size, flag);
        shmem_id1=shmget(key,sizeof(int),flag);
        if (shmem_id == -1)
        {
            perror ("shmget failed");
            exit (1);
        }
        buffer = (char *) shmat (shmem_id, (void *) NULL, 1023);
        count= (int *)shmat( shmem_id1,(void *) NULL,1023);
        if (buffer == (void *) -1)
        {
            perror ("shmat failed");
            exit (2);
        }
        /* Done with the program, so detach the shared segment and terminate */
    //    printf("%s",buffer);
        shmdt ( (void *)  buffer);
    }
    Just looking at the memcpy part, it appears as though you assign buffer an address and then delete the shared segment before you exit the routine. Then you try to use buffer which now points to nothing (you deleted the segment). My guess is that this has something to do with the other problems.

  3. #3
    Just Joined!
    Join Date
    Sep 2010
    Posts
    2
    I removed that delete part, still the status is the same..

  4. $spacer_open
    $spacer_close
  5. #4
    Linux Newbie
    Join Date
    Apr 2007
    Posts
    119
    I copied your code and ran it. You are not segmenting at the memcpy. When I commented out the memcpy, I still got the segfault.

    My suggestion is to use a debugger or print statements to see where it is segfaulting.

  6. #5
    Linux Newbie
    Join Date
    Apr 2007
    Posts
    119
    I take back what I said. I didn't realize you were reading in a file.

    Your memcpy segfault is caused because you are passing the buffer pointer to a function, changing where the buffer points and then returning to the main function. The problem is, the change does not persist outside of the function because you are not changing the contents of the memory address of the pointer, but the pointer value.

    If you return the sharedmem segment address from the function and assign it that way, you will not get the segfault.
    Code:
    buffer = sharedmem(count);
    As far as the hanging, probably related to the signals. Try taking them out and adding them one at a time to figure out where.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •