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 ...
- 09-20-2010 #1Just 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.
Thanks,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); }
Abhishek
- 09-20-2010 #2Linux Newbie
- Join Date
- Apr 2007
- Posts
- 119
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.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); }
- 09-21-2010 #3Just Joined!
- Join Date
- Sep 2010
- Posts
- 2
I removed that delete part, still the status is the same..
- 09-21-2010 #4Linux 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.
- 09-21-2010 #5Linux 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.
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.Code:buffer = sharedmem(count);


Reply With Quote