Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Apr 28th, 2005, 1:10 AM   #1
epswing
Newbie
 
epswing's Avatar
 
Join Date: Feb 2005
Posts: 14
Rep Power: 0 epswing is on a distinguished road
Question signal troubles

I'm trying to jerry rig this thing into submission
Although probably not the "correct" way to do it, I thought this would work.

I'm creating three children, and two pipes. I want to pass a string from child1 to child2 using the first pipe, and from child2 to child3 using the second pipe. It works when I use sleep(1); in child 2, and sleep(2); in child3. I'd now like to pause the children until they hear from a signal sent by the previous child saying "it's ok to proceed".

It reaches the first printf statement, then just sits there and does nothing until I manually kill it. Thoughts?

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

void handler(int sig)
{
	
}

main()
{
	pid_t child1, child2, child3;
	int pipefd1to2[2], pipefd2to3[2];
	pipe(pipefd1to2);
	pipe(pipefd2to3);
	signal(SIGUSR1, handler);
	
	char * mesg = "Don't Panic!", buf[strlen(mesg)+1];
	
	if (child1 = fork() == 0) {      // child1

		write(pipefd1to2[1], mesg, strlen(mesg)+1);
		printf("\nchild1: writing '%s' into pipe1\n\n", mesg); // <--prints successfully

		kill(child2, SIGUSR1);
		exit(0);

	}
	else if (child2 = fork() == 0) { // child2

		pause();

		read(pipefd1to2[0], buf, strlen(mesg)+1);
		printf("child2: reading '%s' from pipe1\n", buf);

		write(pipefd2to3[1], buf, strlen(mesg)+1);
		printf("child2: writing '%s' into pipe2\n\n", buf);

		kill(child3, SIGUSR1);
		exit(0);

	}
	else if (child3 = fork() == 0) { // child3

		pause();

		read(pipefd2to3[0], buf, strlen(mesg)+1);
		printf("child3: reading '%s' from pipe2\n\n", buf);

		exit(0);

	}
	
	waitpid(child1, NULL, 0);
	waitpid(child2, NULL, 0);
	waitpid(child3, NULL, 0);

	return 0;
}
epswing is offline   Reply With Quote
Old Apr 28th, 2005, 1:12 AM   #2
epswing
Newbie
 
epswing's Avatar
 
Join Date: Feb 2005
Posts: 14
Rep Power: 0 epswing is on a distinguished road
If you're wondering, I'm basing the above on something I quickly wrote and know works.

/* 
 * The child pauses, waiting for some signal.  The parent outputs "I am the
 * parent." and sends the user-defined signal SIGUSR1 to the child.  Child
 * unpauses, outputs "I am the child.".  Parent then waits on child.
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <signal.h>

void handler(int sig)
{

}

int main()
{
	pid_t pid;
	signal(SIGUSR1, handler);
	
	pid = fork();
	
	if (pid == 0) { // child: waits for some signal before continuing
		pause();
		printf("I am the child.\n");
		exit(0);
	}
	else { // parent: sends child a signal to continue
		printf("I am the parent.\n");
		kill(0, SIGUSR1);
		wait(NULL);
		exit(0);
	}
}
epswing is offline   Reply With Quote
Old Apr 28th, 2005, 7:33 AM   #3
mackenga
Professional Programmer
 
Join Date: Mar 2005
Location: Glasgow, Scotland
Posts: 328
Rep Power: 4 mackenga is on a distinguished road
When child1 tries to signal with kill(), the child2 variable doesn't yet contain the pid of the second child, which doesn't exist yet at the time when child1 gets forked. Since a complete copy of the data is (at least conceptually) made on the fork(), child1 will never have access to child2's pid unless you fork all the children first.

This means child1's kill() goes astray (it's sent to some random, probably nonexistant process, depending on the value in the uninitialised child2 variable), which means child2 never receives it and never wakes up, hence the hang.

I'm not about to write a whole program here, or try to correct yours for you, but the idea would be to fork the children first or in a better order. child1 needs child2's pid, but the other way around is not the case; so create child2 first, and then you can use child2's pid in child 1, if you see what I mean.

I haven't thought deeply about whether reordering the branches on your if statement will do this job, but I think it might. If not, you need to restructure a bit more.

Hope this helps.

Last edited by mackenga; Apr 28th, 2005 at 7:36 AM. Reason: Added helpful information :)
mackenga is offline   Reply With Quote
Old Apr 28th, 2005, 1:25 PM   #4
epswing
Newbie
 
epswing's Avatar
 
Join Date: Feb 2005
Posts: 14
Rep Power: 0 epswing is on a distinguished road
Ahh, child2's pid is not initialized in child1. Yeah that does help, thanks.
epswing is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 10:28 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC