The fork() System Call

7
1. The fork() System Call System call fork() is used to create processes. It takes no arguments and returns a process ID. The purpose of fork() is to create a new process, which becomes the child process of the caller. After a new child process is created, both processes will execute the next instruction following the fork() system call. Therefore, we have to distinguish the parent from the child. This can be done by testing the returned value of fork(): If fork() returns a negative value, the creation of a child process was unsuccessful. fork() returns a zero to the newly created child process. fork() returns a positive value, the process ID of the child process, to the parent. The returned process ID is of type pid_t defined in sys/types.h. Normally, the process ID is an integer. Moreover, a process can use function getpid() to retrieve the process ID assigned to this process. Therefore, after the system call to fork(), a simple test can tell which process is the child. Please note that Unix will make an exact copy of the parent's address space and give it to the child. Therefore, the parent and child processes have separate address spaces. Let us take an example to make the above points clear. This example does not distinguish parent and the child processes. Click here to download this file fork-01.c. #include <stdio.h> #include <string.h> #include <sys/types.h> #define MAX_COUNT 200 #define BUF_SIZE 100 void main(void) { pid_t pid; int i; char buf[BUF_SIZE]; fork(); pid = getpid(); for (i = 1; i <= MAX_COUNT; i++) { sprintf(buf, "This line is from pid %d, value = %d\n", pid, i); write(1, buf, strlen(buf)); } } Suppose the above program executes up to the point of the call to fork() (marked in red color): Page 1

Transcript of The fork() System Call

Page 1: The fork() System Call

1. The fork() System Call

System call fork() is used to create processes. It takes no arguments and returns a process ID. The purpose of fork() is to create a new process, which becomes the child process of the caller. After a new child process is created, both processes will execute the next instruction following the fork() system call. Therefore, we have to distinguish the parent from the child. This can be done by testing the returned value of fork():

If fork() returns a negative value, the creation of a child process was unsuccessful. fork() returns a zero to the newly created child process. fork() returns a positive value, the process ID of the child process, to the parent. The returned

process ID is of type pid_t defined in sys/types.h. Normally, the process ID is an integer. Moreover, a process can use function getpid() to retrieve the process ID assigned to this process.

Therefore, after the system call to fork(), a simple test can tell which process is the child. Please note that Unix will make an exact copy of the parent's address space and give it to the child. Therefore, the parent and child processes have separate address spaces.

Let us take an example to make the above points clear. This example does not distinguish parent and the child processes. Click here to download this file fork-01.c.

#include <stdio.h>#include <string.h>#include <sys/types.h>

#define MAX_COUNT 200#define BUF_SIZE 100

void main(void){ pid_t pid; int i; char buf[BUF_SIZE];

fork(); pid = getpid(); for (i = 1; i <= MAX_COUNT; i++) { sprintf(buf, "This line is from pid %d, value = %d\n", pid, i); write(1, buf, strlen(buf)); } }

Suppose the above program executes up to the point of the call to fork() (marked in red color):

If the call to fork() is executed successfully, Unix will

make two identical copies of address spaces, one for the parent and the other for the child. Both processes will start their execution at the next statement following the fork() call. In this

case, both processes will start their execution at the assignment statement as shown below:

Page 1

Page 2: The fork() System Call

Both processes start their execution right after the system call fork(). Since both processes have identical but separate address spaces, those variables initialized before the fork() call have the same values in both address spaces. Since every process has its own address space, any modifications will be independent of the others. In other words, if the parent changes the value of its variable, the modification will only affect the variable in the parent process's address space. Other address spaces created by fork() calls will not be affected even though they have identical variable names.

2.

List the system calls used for process management:

System calls Descriptionfork() To create a new processexec() To execute a new program in a processwait() To wait until a created process completes its executionexit() To exit from a process executiongetpid() To get a process identifier of the current processgetppid() To get parent process identifiernice() To bias the existing priority of a processbrk() To increase/decrease the data segment size of a process

3 Environment variables 

Environment variables are a set of dynamic named values that can affect the way

running processes will behave on a computer.

Or (from ignou c library )

When a program is executed, it receives information about the context in which it was invoked in two ways. The first mechanism uses the argv and argc arguments to its main function, and is discussed inProgram Arguments. The second mechanism uses environment variables and is discussed in this section.

The argv mechanism is typically used to pass command-line arguments specific to the particular program being invoked. The environment, on the other hand, keeps track of information that is shared by many programs, changes infrequently, and that is less frequently used.

They can be said in some sense to create the operating environment in which a process runs. For

example, an environment variable with a standard name can store the location that a particular

computer system uses to store temporary files—this may vary from one computer system to another. A

process which invokes the environment variable by (standard) name can be sure that it is storing

temporary information in a directory that exists and is expected to have sufficient space.

Page 2

Page 3: The fork() System Call

Working principles of environment variables

A few simple principles govern how environment variables BY INSTALLING, achieve their effect.

[edit]Local to process

Environment variables are local to the process in which they were set. That means if we open two terminal windows (Two different processes running shell) and change value of environment variable in one window, that change will not be seen by other window.

[edit]Inheritance

When a child process is created, it inherits all the environment variables and their values from the parent process. Usually, when a program calls another program, it first creates a child process by forking, then the child adjusts the environment as needed and lastly the child replaces itself with the program to be called. This procedure gives the calling program control over the environment of the called program.

[edit]Case sensitive

In Unix and Unix-like systems the names of environment variables are case sensitive.

[edit]Persistence

Environment variables persistence can be session-wide or system-wide.

How can a parent and child process communicate? 

A parent and child can communicate through any of the normal inter-process communicationschemes (pipes, sockets, message queues, shared memory), but also have some special ways to communicate that take advantage of their relationship as a parent and child. One of the most obvious is that the parent can get the exit status of the child.

One of the most obvious is that the parent can get the exit status of the child.Since the child inherits file descriptors from its parent, the parent can open both ends of a pipe, fork, then the parent close one end and the child close the other end of the pipe. This is what happens when you call the popen() routine to run another program from within yours, i.e. you can write to the file descriptor returned from popen() and the child process sees it as its stdin, or you can read from the file descriptor and see what the program wrote to its stdout. (The mode parameter to popen() defines which; if you want to do both, then you can do the plumbing yourself without too much difficulty.) Also, the child process inherits memory segments mmapped anonymously (or by mmapping the special file `/dev/zero') by the parent; these shared memory segments are not accessible from unrelated processes. 

what is a zombie process?

On Unix and Unix-like computer operating systems, a zombie process or defunct process is

a process that has completed execution but still has an entry in the process table. This entry is still

needed to allow the parent process to read its child's exit status. The term zombie process derives from

the common definition of zombie—an undead person. In the term's metaphor, the child process has

"died" but has not yet been "reaped". Also, unlike normal processes, the kill command has no effect on a

zombie process.

Page 3

Page 4: The fork() System Call

When a process ends, all of the memory and resources associated with it are deallocated so they can be

used by other processes. However, the process's entry in the process table remains. The parent can read

the child's exit status by executing the wait system call, at which stage the zombie is removed.

The wait call may be executed in sequential code, but it is commonly executed in a handler for

the SIGCHLD signal, which the parent receives whenever a child has died.

After the zombie is removed, its process ID and entry in the process table can then be reused. However,

if a parent fails to call wait, the zombie will be left in the process table. In some situations this may be

desirable, for example if the parent creates another child process it ensures that it will not be allocated

the same process ID. On modern UNIX-like systems (that comply with SUSv3 specification in this

respect), the following special case applies: if the parent explicitly ignores SIGCHLD by setting its handler

to SIG_IGN (rather than simply ignoring the signal by default) or has the SA_NOCLDWAIT flag set, all child

exit status information will be discarded and no zombie processes will be left.

A zombie process is not the same as an orphan process. An orphan process is a process that is still

executing, but whose parent has died. They do not become zombie processes; instead, they are adopted

by init (process ID 1), which waits on its children.

What are the process state in unix?

If your process makes a system call, then while the system call code is being run in the kernel, is your process READY, RUNNING or BLOCKED?

Process states in Linux:

Running: Process is either running or ready to run

Interruptible: a Blocked state of a process and waiting for an event or signal from another process

Uninterruptible:- a blocked state. Process waits for a hardware condition and cannot handle any signal

Stopped: Process is stopped or halted and can be restarted by some other process

Zombie: process terminated, but information is still there in the process table.

Unix - What are the process states in Unix? - May 12, 2009 at 13:50 pm by Vidya Sagar

What are the process states in UNIX?

UNIX has the following process states:

1) Running2) Suspended (sleep)3) Stopped 4) Zombie

What Happens when you execute a program?

When you execute a program on your UNIX system, the system creates a special environment for

that program. This environment contains everything needed for the system to run the program as if no

Page 4

Page 5: The fork() System Call

other program were running on the system. Each process has process context, which is everything that is

unique about the state of the program you are currently running. Every time you execute a program the

UNIX system does a fork, which performs a series of operations to create a process context and then

execute your program in that context. The steps include the following:

Allocate a slot in the process table, a list of currently running programs kept by UNIX.

Assign a unique process identifier (PID) to the process

iCopy the context of the parent, the process that requested the spawning of the new process.

Return the new PID to the parent process. This enables the parent process to examine or control

the process directly.

After the fork is complete, UNIX runs your program.

22. What Happens when you execute a command?

When you enter 'ls' command to look at the contents of your current working directory, UNIX does a

series of things to create an environment for ls and the run it: The shell has UNIX perform a fork. This

creates a new process that the shell will use to run the ls program. The shell has UNIX perform an exec of

the ls program. This replaces the shell program and data with the program and data for ls and then starts

running that new program. The ls program is loaded into the new process context, replacing the text and

data of the shell. The ls program performs its task, listing the contents of the current directory.

how do you execute one program from within another?

There are various ways to run another program from within your own. Most of the good ones are compiler dependant, so best research your help files before going too far 

In all the example code below you'll find some sample output. In the cases where a child program has been invoked, this source was used to make that child:

#include <stdio.h>

int main(int argc, char *argv[] ){ int i = 0; printf("I am the child\n"); while (--argc) printf ("Arg %d %s\n", ++i, *++argv); return 0;}

Now, we'll start with a simple example of system().

OPTION 1 - system()

Prototype:int system (const char * s);

This function executes a command specified in s, and returns after the command has been completed. A few reasons not to use this method are:

Page 5

Page 6: The fork() System Call

The child program is uninterruptible from the parent program. This means that you cannot stop the program you have started. If it takes 5 hours to complete, that's how long your program will wait 

You cannot communicate or share variables with the child process

For various security reasons, its unsafe and may leave your system open to exploitation.

In system terms, its relatively slow.

Having said that, it is easy to use, and these things have their place. Here is a example of how to use it.

What are various IDs associated with a process?

Unix identifies each process with a unique integer called ProcessID. The process that executes the request for creation of a process is called the 'parent process' whose PID is 'Parent Process ID'. Every process is associated with a particular user called the 'owner' who has privileges over the process. The identification for the user is 'UserID'. Owner is the user who executes the process. Process also has 'Effective User ID' which determines the access privileges for accessing resources like files.getpid() -process idgetppid() -parent process idgetuid() -user idgeteuid() -effective user id

Page 6