![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Newbie
Join Date: Feb 2005
Posts: 14
Rep Power: 0
![]() |
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;
} |
|
|
|
|
|
#2 |
|
Newbie
Join Date: Feb 2005
Posts: 14
Rep Power: 0
![]() |
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);
}
} |
|
|
|
|
|
#3 |
|
Professional Programmer
Join Date: Mar 2005
Location: Glasgow, Scotland
Posts: 328
Rep Power: 4
![]() |
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 :) |
|
|
|
|
|
#4 |
|
Newbie
Join Date: Feb 2005
Posts: 14
Rep Power: 0
![]() |
Ahh, child2's pid is not initialized in child1. Yeah that does help, thanks.
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|