Create new process in separate function [c] - c

I wanna create spare process (child?) in specific function called eg. void process(). I want just to create that child process and do nothing with it. I just wanna it alive and do nothing while main() of my app will be working as I want.
In some point of my app's main() I will be killing child process and then respawn it again. Any ideas how to do that ?
I have something like that but when I'm using this function to create process I get everything twice. Its like after initiation of process() every statement is done twice and i dont want it. After adding sleep(100) after getpid() in child section seems working fine but I cannot kill it.
int process(int case){
if(case==1){
status=1;
childpid = fork();
if (childpid >= 0) /* fork succeeded */
{
if (childpid == 0) /* fork() returns 0 to the child process */
{
printf("CHILD PID: %d\n", getpid());
}
/* fork() returns new pid to the parent process *//* else
{
}*/
}
else
{
perror("fork");
exit(0);
}
}
else{
if(status!=0){
status=0;
//kill!!!!
system(a); //getting kill -9 PID ; but PID is equal 0 here...
printf("\nkilling child");
}
}
}
how to just spawn new child process and let it just exist, like some sort of worker in C#?

Assuming you are in Linux, here's an example that might clarify your view: parent process spawns a child, the child calls pause() which suspends it until a signal is delivered, and finally parent process kill's the child with SIGKILL.
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
int main()
{
pid_t pid;
pid = fork();
if (pid < 0) { perror("fork"); exit(0); }
if (pid == 0) {
printf("Child process created and will now wait for signal...\n");
pause(); //waits for signal
}
else {
//do some other work in parent process here
printf("Killing child (%ld) from parent process!", (long) pid);
kill(pid, SIGKILL);
}
return 0;
}
Please note that fork() returns:
<0 on failure
0 in child process
the child's pid in parent process.

Related

Creation of process with fork

I'm trying to understand how to create fork trees,is there any simple way to understand that?
Exemple:
include<stdio.h>
include<unistd.h>
void main(){
fork();
if fork();
if fork();
fork();
sleep(10);
}
Every time you are calling fork() you are creating a Child that has the exact code the father has until this moment, but its own memory map.
Then you have to 2 processes with the same code. If you want to make them do something different you have to use fork()'s return. Fork returns the pid of the child and ''assigns'' it at Father's memory. Through that mechanism Father can refer to the child using its pid (process ID) which is only known to him. If child tries to see the exact pid created for it through fork(), it simply can't and would be zero (because fork return PID to a process for other child processes).
Example code of the above is the bellow:
void main(void)
{
char sth[20]="something";
pid_t pid;
pid = fork(); // Create a child
// At this line (so this specific comment if you may like) has 2 processes with the above code
printf("I am process with ID<%ld> and i will print sth var <%s>", getpid(),sth);
// The above printf would be printed by both processes because you haven't issued yet a way to make each process run a different code.
// To do that you have to create the following if statement and check PID according to what said above.
if (pid == 0) // If PID == 0, child will run the code
printf("Hello from child process with pid <%ld>",getpid());
printf(", created by process with id <%ld>\n",getppid());
else // Else the father would run the code
printf("Hello from father process with pid <%ld>",getpid());
}
I tried to be as naive as i could. Hope it helps somehow.
From linux manual:
fork() creates a new process by duplicating the calling process.
Basically it creates a new process, referred to as the child, which is an exact duplicate, with same code, of the calling process, referred to as the parent, except for few things (take a look at man fork). It returns the child process ID if you're the parent, 0 if you're the child or -1 (and sets errno) to the parent on failure. Here's a code example of a fork tree:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
/*
* I'm going to create a fork tree
*
*/
int main(){
pid_t pid; /*Use it for fork() calls*/
pid = fork(); /*Generating the first child*/
if(pid == 0){ /*I'm the child*/
pid_t pid_child = fork();
if(pid_child == 0){ /*I'm the grandchild*/
printf("I'M THE GRANDCHILD\n");
return 0; /*Terminates the new process*/
}else if(pid_child > 0){ /* I'm the child*/
waitpid(pid_child,NULL,0);
printf("I'M THE CHILD\n");
return 0; /*Terminates the new process*/
}
}else if(pid > 0){ /*I'm the parent*/
waitpid(pid,NULL,0); /*Waiting for the child*/
printf("I'M THE PARENT\n");
}
return 0;
}

Why execution stops after printing "This is the child process!"?

//Why not execute all the conditions(parent and child)?
#include<stdio.h>
#include<unistd.h>
int main(){
pid_t pid; //process-id
printf("This is where we start...\n");
pid = fork();
//For the child process
if(pid==0){
printf("This is the child process!\n");
return 1;
}
//This should have been printed
if(pid>0){
printf("This is the parent!\n");
}
//THis may/may not be printed - its ok
if(pid < 0){
printf("Fork failed!");
}
return 0;
}
It was excepted that after returning from the child, the parent should have been executed but this is what i get:
$ This is the child process!
What am i missing? why not child as well as the parent block printed?
The program is completely fine. When a fork is performed, a new child process is created. The child process created is independent of the parent and it is completely possible that the parent does not wait for the child to complete its execution.
If you want that the parent execution resumes once the child is complete, you should use the wait() function, that makes sure that a forked child is executed before parent continues.
Try updating your code as follows:
#include<stdio.h>
#include<unistd.h>
#include <sys/wait.h> //Add this header
int main()
{
pid_t pid; //process-id
int status; //A variable to get the status of the child, i.e. if error or success
printf("This is where we start...\n");
pid = fork();
if(pid==0){
printf("This is the child process!\n");
return 1;
}
if(pid>0){
wait(&status); //Function to wait for child
printf("This is the parent!\n");
}
if(pid < 0){
printf("Fork failed!");
}
return 0;
}
For more information check out this link: Forking a Process and Parent-Child execution - Linux : C Programming

Create multiple child processes in UNIX

I want to write an UNIX program that creates N child processes, so that the first process creates one child process, then this child creates only one process that is its child, then the child of the child creates another child etc.
Here's my code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int N=3;
int i=0;
printf("Creating %d children\n", N);
printf("PARENT PROCESS\nMy pid is:%d \n",getpid() );
for(i=0;i<N;i++)
{
pid_t pid=fork();
if(pid < 0)
{
perror("Fork error\n");
return 1;
}
else if (pid==0) /* child */
{
printf("CHILD My pid is:%d my parent pid is %d\n",getpid(), getppid() );
}
else /* parrent */
{
exit(0);
}
}
return 0;
}
The output that I expect is in the form:
Creating 3 children
PARENT PROCESS
My pid is 1234
CHILD My pid is 4567 my parent pid is 1234
CHILD My pid is 3528 my parent pid is 4567
CHILD My pid is 5735 my parent pid is 3528
The output I get in the terminal is
Creating 3 children
PARENT PROCESS
My pid is:564
CHILD My pid is:5036 my parent pid is 564
User#User-PC ~
$ CHILD My pid is:4804 my parent pid is 1
CHILD My pid is:6412 my parent pid is 4804
The problem is that the program doesn't seem to terminate. I should use Ctrl+C to get out of the terminal, which is not normal. Can you help me to fix this issue?
The children die when the parent dies.
In your case the parent exits before all the children have been created.
Try waiting for the children before exiting:
else /* parrent */
{
int returnStatus;
waitpid(pid, &returnStatus, 0); // Parent process waits for child to terminate.
exit(0);
}
try to wait the process with wait(NULL);
pid_t child = fork();
if (child == -1)
{
puts("error");
exit(0);
}
else if (child == 0)
{
// your action
}
else
{
wait(&child);
exit(0);
}
so your father will wait the child process to exit
The proposed cure is correct, but the reason stated is wrong. Children do not die with the parent. The line
CHILD My pid is:4804 my parent pid is 1
clearly indicates that by the time child called getppid() its parent is already dead, and the child has been reparented to init (pid 1).
The real problem is that after the child prints its message, it continues to execute the loop, producing more children, making your program into a fork bomb.

Killing a child process from a signal handler

I'm writing a simple shell, and I have to fork a child process an external program using execv. I have to send the signal TSTP(Cntl+Z) to the signal handler, and then kill the currently running child process. My problem is I can't find a way to pass the Child pid into the signal handler. If i do a getpid() in the handler, it just returns the parent pid. I also tried setting the child pid as getpid() inside the child process, and having that variable as a global variable, but that also didn't work. Here is some of the code I have so far.
void handler(int);
//in main
if (!built_in_cmd(myArgc,myArgs)) {
pid_t pid;
char *x = myArgs[0];
if((pid=fork())<0)
printf("Parent: fork() process failed");
else {
if (pid == 0) {
y=getpid();
printf("Parent: My child has been spawned. %d %d\n",y,getppid());
execv(x, myArgs);
exit(0);
}
else {
signal(SIGTSTP,handler);
wait(0);
printf("Parent: My child has terminated.\n");
}
}
}
return;
//outside main
void handler(int signo){
kill(idk,SIGKILL);
}
Signals are asynchronous in nature, there's no way to pass any extra state to them except through global variables. Assuming that you only ever have one thread waiting for a child, it's safe to use a global, but otherwise there's no multithread-safe way of doing so:
// At global scope
pid_t child_pid = (pid_t)-1;
...
void myfunc()
{
pid_t pid;
if((pid = fork()) < 0)
...
else if(pid == 0)
...
else
{
child_pid = pid;
...
}
}

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!

Resources