Linux Basic Programming-2

·

4 min read

Duplicating a Process Image:-

You can create a new process by calling fork() . This system call duplicates the current process, creating a new entry in the process table with many of the same attributes as the current process. The new process is almost identical to the original, executing the same code but with its own data space, environment,and file descriptors.

The call to fork in the parent returns the PID of the new child process. The new process continues to execute just like the original, with the exception that in the child process the call to fork returns 0 . This allows both the parent and child to determine which is which.

If fork fails, it returns -1 . This is commonly due to a limit on the number of child processes that a parent may have ( CHILD_MAX ), in which case errno will be set to EAGAIN . If there is not enough space for an entry in the process table, or not enough virtual memory, the errno variable will be set to ENOMEM . A typical code snippet using fork() is:-

pid_t new_pid;
new_pid = fork();
switch(new_pid) {
case -1 :
/* Error */
break;
case 0 :
/* child(new) process */
break;
default :
/* parent process*/
break;
}

full program :-

#include<sys/types.h>
#include<unistd.h>
pid_t fork(void);
#include<stdio.h>
#include<stdlib.h>
int main()
{
pid_t pid;
char *message;
int n;
printf("fork program starting\n");
pid = fork();
switch(pid)
{
case -1:
perror("fork failed");
exit(1);
case 0:
message = "This is the child";
n = 5;
break;
default:
message = "This is the parent";
n = 3;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);
}
exit(0);
}

Output:-

forkdevn.png

How It Works:-

This program runs as two processes. A child is created and prints a message five times. The original process (the parent) prints a message only three times. The parent process finishes before the child has printed all of its messages, so the next shell prompt appears mixed in with the output. When fork is called, this program divides into two separate processes. The parent process is identified by a nonzero return from fork and is used to set a number of messages to print, each separated by one second.

The pid_t data type is a signed integer type which is capable of representing a process ID.
In the GNU C Library, this is an int .

Waiting for a Process:-

When you start a child process with fork() , it takes on a life of its own and runs independently. Sometimes,you would like to find out when a child process has finished. For example, in the previous program, the parent finishes ahead of the child and you get some messy output as the child continues to run. You can arrange for the parent process to wait until the child finishes before continuing by calling wait .


#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *stat_loc);    
`

The wait system call causes a parent process to pause until one of its child processes is stopped. The call returns the PID of the child process. This will normally be a child process that has terminated. The status information allows the parent process to determine the exit status of the child process, that is, the value returned from main or passed to exit . If stat_loc is not a null pointer, the status information will be written to the location to which it points.

forkwaitdevn.c

 #include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int *stat_loc);
#include<unistd.h>
#include<stdio.h>
#include <stdlib.h>
int main()
{
pid_t pid;
char *message;
int n;
int exit_code;
printf("fork program starting\n");
pid = fork();
switch(pid)
{
case -1:
perror("fork failed");
exit(1);
case 0:
message = "This is the child";
n = 5;
exit_code = 37;
break;
default:
message = "This is the parent";
n = 3;
exit_code = 0;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);
}
if (pid != 0) {
int stat_val;
pid_t child_pid;
child_pid = wait(&stat_val);
printf("Child has finished: PID = %d\n", child_pid);
if(WIFEXITED(stat_val))
printf("Child exited with code %d\n", WEXITSTATUS(stat_val));
else
printf("Child terminated abnormally\n");
}
exit(exit_code);
}

Output:-

forwaitdevn.png

How It Works:-

The parent process, which got a nonzero return from the fork call, uses the wait system call to suspend its own execution until status information becomes available for a child process. This happens when the child calls exit ; I gave it an exit code of 37. The parent then continues, determines that the child terminated normally by testing the return value of the wait call, and extracts the exit code from the status information.
The POSIX error function, perror, is used in C and C++ to print an error message to stderr, based on the error state stored in errno. It prints str and an implementation-defined error message corresponding to the global variable errno.