Handling multiple fork()s in c - c

I'm struggling to understand this concept. Let's say I want to run 3 concurrent processes (threads are not an option, this is an assignment).
I would do:
int main(){
fork();
if (getPid() == -1) { //this is the parent
fork(); //make a third process
} else if (getPid() == 0) { //child process
//do child things
}
So from what I've learned the parent pid is -1. And there's two children, both with PID 0?
So then the "parent" can spawn as many children as possible, correct? They will all do child things.
What if I want to do 3 different things? How do I track the PID's so that I have 3 unique
ones?
as per the comments - is this how it's done?
pid_t child2Pid;
pid_t child1Pid = fork();
switch /*if getPid is wrong what do I put here?*/ {
case -1: //parent
child2Pid = fork(); //create another child
case child1Pid :
//do what child1 would do
case child2Pid :
//do what child2 would do

pid_t child1, child2, child3;
if ((child1 = fork()) == 0)
{
// first child stuff goes here
_exit(0);
}
if ((child2 = fork()) == 0)
{
// second child stuff goes here
_exit(0);
}
if ((child3 = fork()) == 0)
{
// third child stuff goes here
_exit(0);
}
// we are in the parent, we have the PIDs of our three
// children in child1, child2, and child3

The whole idea is that you enter fork() once, but leave it twice - once in the parent, once in the child. In the parent, fork() returns the child's PID, in the child, fork() returns 0. -1 means error and there is no child.
So when you call fork(), look at the return value. Like this:
if(fork() > 0) //We're in the parent, and a child was spawned
fork(); //Spawn another.
This will create three processes. Error handling omitted.

**
int main()
{
pid_t pid;
int i;
for(i = 0;i < 3;i++)
{
pid = fork();
}
if(pid == 0)
{
printf("child\n");
}
else if(pid > 0)
{
printf("parent\n");
}
return 0;
}
you can use pid_t = fork() to record the value,and select what you do by the value.**

Related

C, Creating multiple process with same parent [duplicate]

can someone help me about how to create multiple child processes which have the same parent in order to do "some" part of particular job?
for example, an external sorting algorithm which is applied with child processes; each child process sorts a part of data and finally the parent merges them..
EDIT: Maybe I should mention the forking multiple child processes with loop..
Here is how to fork 10 children and wait for them to finish:
pid_t pids[10];
int i;
int n = 10;
/* Start children. */
for (i = 0; i < n; ++i) {
if ((pids[i] = fork()) < 0) {
perror("fork");
abort();
} else if (pids[i] == 0) {
DoWorkInChild();
exit(0);
}
}
/* Wait for children to exit. */
int status;
pid_t pid;
while (n > 0) {
pid = wait(&status);
printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status);
--n; // TODO(pts): Remove pid from the pids array.
}
If you want to launch several forks, you should do it recursively. This is because you must call fork from the parent process. Otherwise, if you launch a second fork, you will duplicate both parent and first child process. Here's an example:
void forker(int nprocesses)
{
pid_t pid;
if(nprocesses > 0)
{
if ((pid = fork()) < 0)
{
perror("fork");
}
else if (pid == 0)
{
//Child stuff here
printf("Child %d end\n", nprocesses);
}
else if(pid > 0)
{
//parent
forker(nprocesses - 1);
}
}
}
I think it would be worth pointing out why threads are more appropriate here:
As you are trying to do a "part" of the job in parallel i assume that your program needs to know about the result of the computation. fork()s of a process don't share more then the initial information after fork(). Every change in one process is unknow to the other and you would need to pass the information as a message (e.g. through a pipe, see "man pipe").
Threads in a process share the same adress space and therefor are able to manipulate data and have them visible toeach other "immediatly". Also adding the benefits of being more lightweight, I'd go with pthreads().
After all: You will learn all you need to know about fork() if you use pthreads anyway.
You can do this with fork. A given parent can fork as may times as it wants. However, I agree with AviD pthreads may be more appropriate.
pid_t firstChild, secondChild;
firstChild = fork();
if(firstChild > 0)
{
// In parent
secondChild = fork();
if(secondChild > 0)
{
// In parent
}
else if(secondChild < 0)
{
// Error
}
else
{
// In secondChild
}
}
else if(firstChild < 0 )
{
// Error
}
else
{
// In firstChild
}

C save forked pid

Hello i have such problem
pid_t pid1;
pid_t pid2;
void switch_files(int sig_type)
{
printf("%d %d\n", pid1, pid2);
}
int main(int argc, char **argv)
{
pid_t lpid1,lpid2;
if ((lpid1 = fork()) == 0)
{
signal(SIGUSR1, switch_files);
//Some work
} else {
pid1 = lpid1;
}
if ((lpid2 = fork()) == 0)
{
signal(SIGUSR2, switch_files);
//Some work
} else {
pid2 = lpid2;
}
while(scanf("%s", input) > 0)
{
write(pipe1[1], input, strlen(input) + 1);
kill(pid1, SIGUSR1);
}
waitpid(pid1, 0, 0);
waitpid(pid2, 0, 0);
}
So i need to have value of pid1 and pid2 in my callback for signals, and at printf i have 0 0 but in main i have normal value of pids. How i can fix this, thank you for any help.
If you want the child to have the pid, simply ask for it:
if ((lpid1 = fork()) == 0)
{
pid1 = getpid();
pid2 = -1; // other child doesn't even exist yet
signal(SIGUSR1, switch_files);
//Some work
exit(0); // you don't want the child to go executing parent code, do you?
}
And
if ((lpid2 = fork()) == 0)
{
//pid1 already set with pid of 1st child
pid2 = getpid();
signal(SIGUSR2, switch_files);
//Some work
exit(0); // you don't want the child to go executing parent code, do you?
}
If you need to the 1st child to have the pid of the 2nd child, then you need to use some form of IPC, so you can communicate to the the 1st child after also 2nd child has been started and its pid is known.
If you want the children to have information, you have to communicate that information to them somehow. You can use a file, a pipe, shared memory, or any mechanism you want. But you have to pass the information somehow.

2 child process does not display a message

I am trying to learn programming on and I don’t understand why I can't get child 2 to print hello. I have also closed both read and write ends of the pipe for the parent because I don’t want the parent to communicate. Any help is much appreciated.
int main ()
{
int fd[2];
pid_t child_pid, child_pid1;
if (pipe(fd) < 0)
{
printf("Pipe error");
}
child_pid = fork (); // child 1
if (child_pid != 0)
{
printf("im child 1");
dup2 (fd[1], STDIN_FILENO);
printf("greetings");
child_pid1 = fork (); //child 2
if (child_pid1 != 0)
{
printf("im child 2");
dup2(fd[0], STDOUT_FILENO);
printf("hello");
}
else if (child_pid1 > 0) //Parent Code
{
close (fd[0]);
close (fd[1]);
}
}
return 0;
}
Your first if clause is wrong.
child_pid = fork (); // child 1
if (child_pid != 0)
{
printf("im child 1");
}
This is not the child but the parent. If it is the child, then pid will be 0, only on the parent you have child_pid != 0.
The same happens in the second if clause as well.
You should do if(child_pid == 0) in both cases, if you want that code to be executed in the child process.

How to use Fork() to create only 2 child processes?

I'm starting to learn some C and while studying the fork, wait functions I got to a unexpected output. At least for me.
Is there any way to create only 2 child processes from the parent?
Here my code:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main ()
{
/* Create the pipe */
int fd [2];
pipe(fd);
pid_t pid;
pid_t pidb;
pid = fork ();
pidb = fork ();
if (pid < 0)
{
printf ("Fork Failed\n");
return -1;
}
else if (pid == 0)
{
//printf("I'm the child\n");
}
else
{
//printf("I'm the parent\n");
}
printf("I'm pid %d\n",getpid());
return 0;
}
And Here is my output:
I'm pid 6763
I'm pid 6765
I'm pid 6764
I'm pid 6766
Please, ignore the pipe part, I haven't gotten that far yet. I'm just trying to create only 2 child processes so I expect 3 "I'm pid ..." outputs only 1 for the parent which I will make wait and 2 child processes that will communicate through a pipe.
Let me know if you see where my error is.
pid = fork (); #1
pidb = fork (); #2
Let us assume the parent process id is 100, the first fork creates another process 101. Now both 100 & 101 continue execution after #1, so they execute second fork. pid 100 reaches #2 creating another process 102. pid 101 reaches #2 creating another process 103. So we end up with 4 processes.
What you should do is something like this.
if(fork()) # parent
if(fork()) #parent
else # child2
else #child1
After you create process , you should check the return value. if you don't , the seconde fork() will be executed by both the parent process and the child process, so you have four processes.
if you want to create 2 child processes , just :
if (pid = fork()) {
if (pid = fork()) {
;
}
}
You can create n child processes like this:
for (i = 0; i < n; ++i) {
pid = fork();
if (pid > 0) { /* I am the parent, create more children */
continue;
} else if (pid == 0) { /* I am a child, get to work */
break;
} else {
printf("fork error\n");
exit(1);
}
}
When a fork statement is executed by the parent, a child process is created as you'd expect. You could say that the child process also executes the fork statement but returns a 0, the parent, however, returns the pid.
All code after the fork statement is executed by both, the parent and the child.
In your case what was happening was that the first fork statement created a child process. So presently there's one parent, P1, and one child, C1.
Now both P1 and C1 encounter the second fork statement. The parent creates another child (c2) as you'd expect, but even the child, c1 creates a child process (c3). So in effect you have P1, C1, C2 and C3, which is why you got 4 print statement outputs.
A good way to think about this is using trees, with each node representing a process, and the root node is the topmost parent.
you can check the value as
if ( pid < 0 )
process creation unsuccessful
this tells if the child process creation was unsuccessful..
fork returns the process id of the child process if getpid() is used from parent process..
You can create a child process within a child process. This way you can have 2 copies of the original parent process.
int main (void) {
pid_t pid, pid2;
int status;
pid = fork();
if (pid == 0) { //child process
pid2 = fork();
int status2;
if (pid2 == 0) { //child of child process
printf("friends!\n");
}
else {
printf("my ");
fflush(stdout);
wait(&status2);
}
}
else { //parent process
printf("Hello ");
fflush(stdout);
wait(&status);
}
return 0;
}
This prints the following:
Hello my friends!

Multiple child process

can someone help me about how to create multiple child processes which have the same parent in order to do "some" part of particular job?
for example, an external sorting algorithm which is applied with child processes; each child process sorts a part of data and finally the parent merges them..
EDIT: Maybe I should mention the forking multiple child processes with loop..
Here is how to fork 10 children and wait for them to finish:
pid_t pids[10];
int i;
int n = 10;
/* Start children. */
for (i = 0; i < n; ++i) {
if ((pids[i] = fork()) < 0) {
perror("fork");
abort();
} else if (pids[i] == 0) {
DoWorkInChild();
exit(0);
}
}
/* Wait for children to exit. */
int status;
pid_t pid;
while (n > 0) {
pid = wait(&status);
printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status);
--n; // TODO(pts): Remove pid from the pids array.
}
If you want to launch several forks, you should do it recursively. This is because you must call fork from the parent process. Otherwise, if you launch a second fork, you will duplicate both parent and first child process. Here's an example:
void forker(int nprocesses)
{
pid_t pid;
if(nprocesses > 0)
{
if ((pid = fork()) < 0)
{
perror("fork");
}
else if (pid == 0)
{
//Child stuff here
printf("Child %d end\n", nprocesses);
}
else if(pid > 0)
{
//parent
forker(nprocesses - 1);
}
}
}
I think it would be worth pointing out why threads are more appropriate here:
As you are trying to do a "part" of the job in parallel i assume that your program needs to know about the result of the computation. fork()s of a process don't share more then the initial information after fork(). Every change in one process is unknow to the other and you would need to pass the information as a message (e.g. through a pipe, see "man pipe").
Threads in a process share the same adress space and therefor are able to manipulate data and have them visible toeach other "immediatly". Also adding the benefits of being more lightweight, I'd go with pthreads().
After all: You will learn all you need to know about fork() if you use pthreads anyway.
You can do this with fork. A given parent can fork as may times as it wants. However, I agree with AviD pthreads may be more appropriate.
pid_t firstChild, secondChild;
firstChild = fork();
if(firstChild > 0)
{
// In parent
secondChild = fork();
if(secondChild > 0)
{
// In parent
}
else if(secondChild < 0)
{
// Error
}
else
{
// In secondChild
}
}
else if(firstChild < 0 )
{
// Error
}
else
{
// In firstChild
}

Resources