Linux C Programming Coding Exercise – Fork


Linux is a powerful Operating System and the C programming language plays a very important role under Linux (compared to Windows).  Most of the Linux kernels are written in C language (note, not C++ with classes and objects).

The C programming language is so powerful and popular that almost every Linux distribution has gcc compiler installed by default (g++ for C++ programs).

To verify your C/C++ compiler, use the gcc –version or g++ –version, which will (for example) prints message:

gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Or

g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

In Linux, multi-tasking is made possible and easier with fork. On Windows platforms, the cost of creating multi processes is higher than multithreading. Threads are considered as a light-weight process where threads share the same ‘local’ information such as file handles. On Linux, creating processes (independent with each other, each has their own memory space) is so easy that it has been used to enable multi tasking (creating multithreads in Linux is somehow more complicated).

The most important function for multitasking in Linux C is fork. It is declared in unistd.h. The fork method will clone a separate/independent process that almost has everything identical to its original/parent process except process id. If in any case the fork operation fails (such as out of memory), it will return -1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
 
int main() {
        pid_t pid;
        switch (pid = fork()) {
                case -1:
                        perror("Fork Failed");
                        break;
                case 0: // child process
                        execl("/bin/ls", "ls", "-1", (char *)0);
                        perror("exec failed");
                        break;
                default: // parent process
                        wait((int *)0); // wait for child to finish
                        printf ("%s\n", "ls completed");
                        exit(0);
        }
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
        pid_t pid;
        switch (pid = fork()) {
                case -1:
                        perror("Fork Failed");
                        break;
                case 0: // child process
                        execl("/bin/ls", "ls", "-1", (char *)0);
                        perror("exec failed");
                        break;
                default: // parent process
                        wait((int *)0); // wait for child to finish
                        printf ("%s\n", "ls completed");
                        exit(0);
        }
}

The pid_t declares the type (in 32 bit, it is effectively the same as unsigned int) for storing process ID. The child process forked will return ZERO for fork() but its parent process will return the child’s process ID (which is larger than ZERO).

The fork() creates a new process by duplicating the calling process. The new process, referred to as the child, is an exact duplicate of the calling process, referred to as the parent.

In the above example, the child process will try to execute the external command /bin/ls using the method execl which takes the first parameter as the full executable file path, the second parameter is argv[0] and the third is argv[1] and so on, the last parameter is null pointer. In the case of failure, it will return -1 otherwise, it will not return at all. So the perror will print error message to stderr in case execution is not successful.

Use perror() to print a message to stderr that corresponds to errno. You use fprintf() to print anything to stderr. perror() is a very specialized printing function and equivalent to the following:

1
2
3
4
if (str)
    fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
    fprintf(stderr, "%s\n", strerror(errno));
if (str)
    fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
    fprintf(stderr, "%s\n", strerror(errno));

Finally, the wait() in the parent process will wait until one of its child processes terminates.

Use gcc -o fork fork.c to compile the program and it goes like this:

-bash-3.2$ gcc -o fork fork.c
-bash-3.2$ ./fork
fork
fork.c
ls completed

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
719 words
Last Post: Understanding Tail Recursion - Visual Studio C++ - Assembly View
Next Post: Coding Exercise - C ++ - Solve Integer Split using Dynamic Programming - 3 Implementation

The Permanent URL is: Linux C Programming Coding Exercise – Fork

Leave a Reply