Problem with signals - 3 process communication


 
Thread Tools Search this Thread
Top Forums Programming Problem with signals - 3 process communication
# 1  
Old 05-02-2006
Problem with signals - 3 process communication

Hello,
I would like to ask you for a little help with program I'm working on. I have problems with signals and synchronizing processes (I'm quite new to this part of programming).

Process "parent" creates new child process "child1" and this process creates new child process "child2". The "child2" process sends a SIGUSR2 signal to "child1" process to inform that he is ready to do something. When "child1" receives SIGUSR2 from "child2", he sends a SIGUSR2 signal to "parent" process to inform that he is ready too. When "parent" receives SIGUSR2 from "child1", he sends SIGUSR1 to "child1". Now "child1" do something. When finished, "child1" sends SIGUSR2 to "child2". Now "child2" do something. When finished, sends SIGUSR2 to "child1" and ends. When "child1" receives SIGUSR2, he sends SIGUSR2 to "parent" and ends. When "parent" receives SIGUSR2, he does something and ends.

SIGUSR1 SIGUSR1
parent ------------> child1 ------------> child2
<----------- <-----------
SIGUSR2 SIGUSR2

Hope you understand :)
Below is my code. If you are familiar with signals, can you please cut&paste the code and spend several minutes of your time to try to find what is wrong?

Expected output should be:
* Child2: sending SIGUSR2 to child1
* Child1: child2 is ready
* Parent: child1 is ready
Child1: received signal from parent, do something
Child2: received signal from child1, do something
*** child2 end ***
*** child1 end ***
Parent: received signal from child1, do something
*** parent end ***

But I only get:
* Child2: sending SIGUSR2 to child1
* Child1: child2 is ready
* Parent: child1 is ready
Child1: received signal from parent, do something

And sometimes even without the last sentence.

Thanks you very much for any help.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define true 1
#define false 0


pid_t pid_child2=0, pid_child1=0, pid_parent=0;
sigset_t pMask, pOldMask, cMask, cOldMask;
int child1_ready=0, child2_ready=0;

/* signal handler for parent */
void sig_parent(int sig)
{
  if ((sig==SIGUSR2) && (child1_ready==0)) {
      child1_ready=1;
      printf("* Parent: child1 is ready\n");
      kill(pid_child1, SIGUSR1); 	// send SIGUSR1 to child1
  } else
  if (sig==SIGUSR2) {
      printf("Parent: received signal from child1, do something\n");
      printf("*** Parent end ***\n");
      exit(0);
  }
  return;
}

/* signal handler for child1 */
void sig_child1(int sig)
{
  if (sig==SIGUSR1) {
      printf("Child1: received signal from parent, do something\n");
      kill(pid_child2, SIGUSR1); // send SIGUSR1 to child2
  } else
  if ((sig==SIGUSR2) && (child2_ready==0)) {
      child2_ready=1;
      printf("* Child1: child2 is ready\n");
      kill(pid_parent, SIGUSR2); 	// inform parent
  } else
  if (sig==SIGUSR2) {
      printf("*** child1 end***\n");
      kill(pid_parent, SIGUSR2);	// inform parent
      exit(0);
  }
  
  return;
}

void sig_child2(int sig)
{
  if (sig==SIGUSR1) {
      printf("Child2: received signal from child1, do something\n");
      kill(pid_child1, SIGUSR2);	// inform child1
      printf("*** child2 end ***\n");
      exit(0);
  } else
  if (sig==SIGUSR2) {
      printf("* Child2: sending SIGUSR2 to child1\n");
      kill(pid_child1, SIGUSR2); 	// inform child1
  }  
  return;
}

/* child2 code */
void child2(void)
{
  pid_child1=getppid(); 			// child2 knows its parent (child1)
  if (signal(SIGUSR1, sig_child2)==SIG_ERR) {
    fprintf(stderr, "Can't catch SIGUSR1.");
  }
  if (signal(SIGUSR2, sig_child2)==SIG_ERR) {
    fprintf(stderr, "Can't catch SIGUSR2.");
  }
  sig_child2(SIGUSR2); 				// start the communication
  for (;;) sigsuspend(&cOldMask);  		// wait for signal
}


void child1(void)
{
  pid_parent=getppid(); 			// child1 knows its parent (parent)

  sigemptyset(&cMask);
  sigaddset(&cMask, SIGUSR1);
  sigaddset(&cMask, SIGUSR2);
  sigprocmask(SIG_BLOCK, &cMask, &cOldMask);


  pid_t pid=fork(); 

  if (pid==0) {     			// we are in the child process
    child2();
  } else {
    if (pid>0) {   			// we are in the parent process
      pid_child2=pid;
      if (signal(SIGUSR1, sig_child1)==SIG_ERR) { 
        fprintf(stderr, "Can't catch SIGUSR1.");
      }
      if (signal(SIGUSR2, sig_child1)==SIG_ERR) {
        fprintf(stderr, "Can't catch SIGUSR2.");
      }
      for (;;) {			// wait for signals
        sigsuspend(&pOldMask);   		
        sigsuspend(&cOldMask);
      }
    } else {
      fprintf(stderr, "Can't create new child.");
    }
  }

  sigprocmask(SIG_UNBLOCK, &cMask, NULL); 
  return;
}

void parent(void)
{
  sigemptyset(&pMask);
  sigaddset(&pMask, SIGUSR1);
  sigaddset(&pMask, SIGUSR2);
  sigprocmask(SIG_BLOCK, &pMask, &pOldMask); 

  pid_t pid=fork(); 

  if (pid==0) {     			// we are in child process
    child1();
  } else {
    if (pid>0) {   			// we are in parent process
      pid_child1=pid;
      if (signal(SIGUSR2, sig_parent)==SIG_ERR) {
        fprintf(stderr, "Can't catch SIGUSR2.");
      }
      for (;;) sigsuspend(&pOldMask);   		// wait for signal
    } else {  
      fprintf(stderr, "Can't create new child.");
    }
  }
  sigprocmask(SIG_UNBLOCK, &pMask, NULL);
  return;
}

int main()
{
  setbuf(stdout,NULL);

  parent();
    
  return 0;
}


Last edited by Perderabo; 05-02-2006 at 06:53 PM.. Reason: Disable smilies and add code tags for readability.
# 2  
Old 05-02-2006
You have at least one race condition. Try installing the signal handlers before you fork. When I tried it, child two sent the signal before the parent installed the handler, so the parent ignored the signal (and then installed the handler and waited for the signal it just discarded.)
# 3  
Old 05-03-2006
It works!!!
Thanks for your advice. But it wasn't the only one problem there. There was also problem with the signal masks. I thought that every process has to create new mask to block signals, but it's enough to do this in the parent process.
(well, I'm not sure if this explanation is correct, but it works and I'm happy Smilie )
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Exit() system call verses process signals

Hello and thanks in advance for any help anyone can offer me I've been reading up on process signal calls (sighup, sigint, sigkill & sigterm) and I understand they all have different methods of terminating a running process. From what I've also read is a exit() actually terminates a process. ... (2 Replies)
Discussion started by: bodisha
2 Replies

2. Programming

Application with communication between process

Hello I would like to create an application with communication between processes, application tightly coupled, have you please an idea about an API or a tool that allows me to generate such application? Thank you so much (11 Replies)
Discussion started by: chercheur857
11 Replies

3. Programming

Fork and then exec problem with signals

Hi All, In my program i am handling SIGHUP signal. In the handler i fork and then exec on child process same binary file which is running. Parent process will die after 10 mins. Now my child process which was exec with same binary file is not receiving SIGHUP signal. Below is the progran code:... (6 Replies)
Discussion started by: sushil_shalin
6 Replies

4. UNIX for Advanced & Expert Users

Process signals as administration

Too generic to post elsewhere, too advanced for the newbie forums. There are some applications within the unix/linux milieu that understand signals such as SIGHUP, etc as instructions to perform administrative tasks (clearing information out of this, disconnect users, etc.) I was just wondering if... (2 Replies)
Discussion started by: thmnetwork
2 Replies

5. Programming

C program using IPC (inter process communication)

i want to write a C chat program that communicates over IPC(inter process communication), that could be run using 2 seperate terminal windows within the same computer. so that wat u type in one terminal window , should appear on the other and vice versa... could some one please help me with the... (2 Replies)
Discussion started by: localp
2 Replies

6. Programming

problem while having a communication with serial port?????

hello, I am gettin problem while sending and recieving data through seial port... when I am sending Data then the reciever end is not able to recieve that data ..... Reciever end is running in infinite loop just polling after some time to check that there is data on the port and then again... (9 Replies)
Discussion started by: arunchaudhary19
9 Replies

7. UNIX for Advanced & Expert Users

Inter-process communication:pipes,doors,etc.

Hi, I am thinking about writing a log daemon for a multi-processed ksh application (yes - I know that high-level language would be a better option). My question is as follows: If many processes (many scripts) will try writing to a single log file: print "message" > common.log Will it work or... (2 Replies)
Discussion started by: adderek
2 Replies

8. Programming

signal in process communication

signal in process communication: I 'm a example in sun_unix that signal in process communication It's here down but I only have freebsd in my machine. how can i do the same in freebsd eg: #include <stdio.h> #include <signal.h> #include <unistd.h> int main( void ){ void... (2 Replies)
Discussion started by: a9711
2 Replies

9. UNIX for Advanced & Expert Users

communication problem between two subnets

We have two Sun Sparc systems running on the xxx.xxx.1.xxx network and can be access fine by machines on that subnet. We are able the ping one of the machines from the xxx.xxx.2.xxx network, but we are not able to ping or communicate with the other machine on the (1) subnet from the (2) subnet. ... (8 Replies)
Discussion started by: pyerj
8 Replies

10. Programming

Inter Process Communication

unix IPC i would like to know the method of usage of semaphores on shared memory segments the topic seems very difficult to understand mainly when difrent proceses communicate instantly and how do i avaoid deadlock situation (2 Replies)
Discussion started by: kamathanil
2 Replies
Login or Register to Ask a Question