Thread: SIGNAL Suspended?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    9

    SIGNAL Suspended?

    Hi,

    First off I am doing homework. I have been looking at this site to view code examples, and I am happy to see the technical caliber on these forums. This is the first time I am programming with signals and I must say that I am "familiar" at best when coding with them.

    My assignment is to sync a parent and a child using signals. I have got that to work (sort of). But the output is quite strange. Anyhow, if anyone can tell me if I am using signals right, and if anyone could explain why I am getting this crazy output, would be awesome.

    Thanks!

    code file w8.c:

    Code:
    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    void mySignalHandler(int sig);
    void sigParent(void);
    void sigChild(void);
    int wait_status;
    pid_t parentPid, childPid, pid;
    
    int main()
    {
    	int i;
    	wait_status = 1; 
    	pid  = fork();
    	switch(pid)
    		{
    		case -1: /* an error occurred */
    		printf("Fork error\n");
    		break;
    
    		case 0: /* this code is executed by the child process */
    		childPid = getpid();
    		signal(SIGCONT, mySignalHandler);
    		signal(SIGSTOP, mySignalHandler);
    			for(i=1; i<10; i++)
    			{
    				if(wait_status == 0)
    				{
    				waitpid(parentPid, NULL, WUNTRACED);
    				}
    				else
    				{
    				printf("Child process, iteration: %d\n", i);
    				sigParent();
    				}
    			}
    		break;
    
    		default: /* this code is executed by the parent process */
    		parentPid = getpid();
    		signal(SIGCONT, mySignalHandler);
    		signal(SIGSTOP, mySignalHandler);
    			for(i=1; i<10; i++)
    			{
    				if(wait_status == 0)
    				{
    				waitpid(childPid, NULL, WUNTRACED);
    				}
    				else
    				{
    				printf("Parent process, iteration: %d\n", i);
    				sigChild();
    				}
    			}/*end for*/
    		break;
    		
    		} /*end switch*/
    }/*end main*/
    
    void mySignalHandler(int sig)
    {
    	if(sig == SIGSTOP)
    		wait_status = 0;
    	else if(sig == SIGCONT)
    		wait_status = 1;
    
    }
    
    void sigParent(void)
    {	
    	kill(parentPid, SIGCONT);
    	raise(SIGSTOP);
    }
    void sigChild(void)
    {
    	kill(childPid, SIGCONT);
    	raise(SIGSTOP);
    }
    and then the output looks like this. Its not always the same either. But it does always say signal suspended:

    Code:
    Parent process, iteration: 1
    
    Child process, iteration: 1
    Parent process, iteration: 2
    Child process, iteration: 2
    Parent process, iteration: 3
    Child process, iteration: 3
    Parent process, iteration: 4
    Child process, iteration: 4
    Parent process, iteration: 5
    Suspended (signal)
    Child process, iteration: 5
    Parent process, iteration: 6
    Child process, iteration: 6
    Parent process, iteration: 7
    Child process, iteration: 7
    Parent process, iteration: 8
    Child process, iteration: 8
    Parent process, iteration: 9
    Child process, iteration: 9
    [8]  + Suspended (signal)            ./a.out

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,337
    The last time anyone used caliber to describe my skills was back in high school when I tried out for the Tennis team. After my try out, the coach came up to me, thanked me for trying out, and then said he didn't need anyone of my caliber on his team at the moment.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You should check the return value of waitpid. What happens with this is that as soon as waitpid() occurs in the child, it returns an error immediately because parentPid is not it's child. It does not wait for anything or perform any purpose.

    And as soon as it occurs in the parent, the parent must wait until the child has completed it's 10 iterations and terminated.

    You should be aware that unless you use this after your printf statements:
    Code:
    fflush(stdout);
    your output may not reflect the real order of events.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Nov 2009
    Posts
    9
    I took out if logic and the wait statement from the child. I also added the flush functions after the printf's. The output still looks the same.

    Did the use of the signals seem correct? They remind of something like a try-catch in Java.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Victor_November View Post
    IThe output still looks the same.
    I'm not sure what you are trying to accomplish. I get different output than what you report, so if you are going for a consistent effect, you are not getting it. Eg:
    Code:
    C 1 (0)
    Child process, iteration: 1
    C 2 (0)
    C 3 (0)
    C 4 (0)
    C 5 (0)
    C 6 (0)
    C 7 (0)
    C 8 (0)
    C 9 (0)
    P 1 (0)
    Parent process, iteration: 1
    P 2 (0)
    P 3 (0)
    P 4 (0)
    P 5 (0)
    P 6 (0)
    P 7 (0)
    P 8 (0)
    P 9 (0)
    The "P" & "C" lines I added in to track the iterations:
    Code:
    printf("P %d (%d)\n",i, x); fflush(stdout);
    "x" was the return value from waitpid, but I removed that too.

    As you can see, not much happens. parentPid remains UNDEFINED as it does in your previously posted code, so of course the parent never receives any signal, and by the time the parent loops, the child has finished and exited also so there is no signal for it.

    The plain truth is there is absolutely no way you can rely on two seperate processes performing a simple for loop in a synchronized manner, as you may have presupposed, without 1) a specific time delay, or 2) some IPC such as signal handling. The code you posted does not really do the later, altho it may appear to in some sense.

    Perhaps the output you posted is from some different code? Anyway, without an actual value for parentPid, you've got nothing substantial going on. This line:
    Code:
    parentPid = getpid();
    is presumably in the wrong place. Forked children DO NOT share variables as with threading. If you print the value of "parentPid" in the child process, you will see it is meaningless, and different from it's value in the parent, where it is set AFTER the fork.
    Last edited by MK27; 11-07-2009 at 05:39 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Nov 2009
    Posts
    9
    Quote Originally Posted by MK27 View Post
    I'm not sure what you are trying to accomplish. I get different output than what you report, so if you are going for a consistent effect, you are not getting it.
    I am trying to fork a process then using two for loops have them alternate by printing a sequences of iterations

    "x" was the return value from waitpid, but I removed that too.

    I added in this statement to the parent

    Code:
    x = waitpid(childPid, NULL, WUNTRACED);
    I print it after the printf stating the iteration number.


    As you can see, not much happens. parentPid remains UNDEFINED as it does in your previously posted code, so of course the parent never receives any signal, and by the time the parent loops, the child has finished and exited also so there is no signal for it.
    I am getting a value for parentPid. See output below.


    The plain truth is there is absolutely no way you can rely on two seperate processes performing a simple for loop in a synchronized manner, as you may have presupposed, without 1) a specific time delay, or 2) some IPC such as signal handling. The code you posted does not really do the later, altho it may appear to in some sense.
    I am trying to use signals to achieve this effect. I take it though from your answer that I am not using them correctly.


    Perhaps the output you posted is from some different code?

    I know I sound new, and its true I am pretty much a noob; but, not that new.

    OK here is the new output:
    The pid: 4 is the value of x set by waitpid. As far as our outputs are concerned, I think it has to do with the fact that I am logged remotely to a university server(?). It is Solaris. I mean: perhaps it is machine differences?

    Code:
    Parent process, iteration: 1 pid: 4
    Parent pid: 9537
    
    Child process, iteration: 1
    Suspended (signal)
    Parent process, iteration: 2 pid: 4
    Parent pid: 9537
    Child process, iteration: 2
    Parent process, iteration: 3 pid: 4
    Parent pid: 9537
    Child process, iteration: 3
    Parent process, iteration: 4 pid: 4
    Parent pid: 9537
    Child process, iteration: 4
    Parent process, iteration: 5 pid: 4
    Parent pid: 9537
    Child process, iteration: 5
    Parent process, iteration: 6 pid: 4
    Parent pid: 9537
    [1]  + Suspended (signal)            ./a.out
    Child process, iteration: 6
    Parent process, iteration: 7 pid: 4
    Parent pid: 9537
    Child process, iteration: 7
    Parent process, iteration: 8 pid: 4
    Parent pid: 9537
    Child process, iteration: 8
    Parent process, iteration: 9 pid: 4
    Parent pid: 9537
    Child process, iteration: 9
    Last edited by Victor_November; 11-07-2009 at 06:53 PM.

  7. #7
    Registered User
    Join Date
    Nov 2009
    Posts
    9
    At this stage, just getting something to work for you is hard enough, so if something works, you consider it "error-free".
    I can assure you that this is not the case.

    Linux and I believe Solaris both conform to POSIX, so it is hard to see how "4" is an indication of success here...
    I am not claiming success. Perhaps I did not make myself clear enough the first time: I am really new at this stuff. MK27 I am not trying to accuse of being wrong; quite the contrary in fact. I am trying to explain to you what I am seeing, and I was just curious why our outputs are different especially if we both have POSIX complaint machines.

    With that said I am going to get my modified code in post it here.

  8. #8
    Registered User
    Join Date
    Nov 2009
    Posts
    9
    Thanks for looking at it for me. As a part of the assignment I can't use sleep. But I will keep plugging away at it.

  9. #9
    Registered User
    Join Date
    Nov 2009
    Posts
    9
    Here is some updated code:


    It works but I still get a Signal Suspended message at a random (or so it appears) place in the output.

    Code:
    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    void sigParent(void);
    void sigChild(void);
    int wait_status;
    pid_t parentPid, childPid, pid;
    
    int main()
    {
    	int i;
    	wait_status = 1;
    	parentPid = getpid();
    	pid  = fork();
    	switch(pid)
    		{
    		case -1: /* an error occurred */
    		printf("Fork error\n");
    		break;
    
    		case 0: 	/* this code is executed by the child process */
    
    			childPid = getpid();
    
    			signal(SIGCONT, SIG_DFL);
    			signal(SIGSTOP, SIG_DFL);
    
    			for(i=1; i<10; i++)
    			{
    				printf("Child process, iteration: %d\n", i);
    				fflush(stdout);
    				sigParent();
    			}
    		break;
    
    		default: 	/* this code is executed by the parent process */
    			
    			waitpid(childPid,NULL, WUNTRACED);
    			signal(SIGCONT, SIG_DFL);
    			signal(SIGSTOP, SIG_DFL);
    
    			for(i=1; i<10; i++)
    			{
    				printf("Parent process, iteration: %d\n", i);
    				fflush(stdout);
    				sigChild();
    			}/*end for*/
    		break;
    		
    		} /*end switch*/
    }/*end main*/
    
    
    
    void sigParent(void)
    {	
    	kill(parentPid, SIGCONT);
    	raise(SIGSTOP);
    }
    void sigChild(void)
    {
    	kill(childPid, SIGCONT);
    	raise(SIGSTOP);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 07-07-2009, 10:05 AM
  2. Replies: 3
    Last Post: 10-15-2008, 09:24 AM
  3. Signal and exception handling
    By nts in forum C++ Programming
    Replies: 23
    Last Post: 11-15-2007, 02:36 PM
  4. NAQ: Everything you never wanted to know about CPP
    By evildave in forum C Programming
    Replies: 21
    Last Post: 12-12-2005, 10:56 AM
  5. signal handling
    By trekker in forum C Programming
    Replies: 2
    Last Post: 07-05-2002, 02:52 AM