C Programming: Creating a child process using “clone”

clone() function is used to create a child process from calling process. Calling process will be the parent process of the child process.

clone() function is used to run a particular function in a separate thread other than the calling process. Unlike fork() function where rest of the code after fork() function call will execute both parent and child processes. But with clone(), a particular function will be executed in separate thread. Once the function is returned, the thread will be closed; means child process will terminates.

The syntax of the function likes below:

int clone(int (*pfn)(void *), void *child_stack, int flags, void *arg, ...);

where pfn is a pointer to a function, which takes void * as an argument and returns an int value. This is the function going to execute in the child process; if the child process successfully created.

Unlike fork(), the process created through clone() function; can share some resources with calling process (the parent).

Calling process’s responsibility to create a stack for child process; hence child_stack argument. Usually stacks grow downward on most of the processors; child_stack should points to the topmost address of the stack memory created by calling process for child process.

And flags indicates what is shared between the calling process and child process. We can pass multiple flags with bitwise-OR.

arg is the argument for the function which points to pfn.

We can pass multiple arguments through clone() function; because of ellipse (three dots).

On function call success, clone() will return the thread ID of the process. If the function fails, it returns “-1”.

Lets take a simple example. Below example will display “Nth” mathematical table. This table will form in child process and display the mathematical table on console window. We have to pass argument “N” when running the program from console; if it is “5”, this program will display “5th” mathematical table.

// sample.c
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <sys/wait.h>

int fn(void *arg)
{
   printf("\nINFO: This code is running under child process.\n");

   int i = 0;
   
   int n = atoi(arg);

   for ( i = 1 ; i <= 10 ; i++ )
      printf("%d * %d = %d\n", n, i, (n*i));

   printf("\n");

   return 0;
}

void main(int argc, char *argv[])
{
   printf("Hello, World!\n");

   void *pchild_stack = malloc(1024 * 1024);
   if ( pchild_stack == NULL ) {
      printf("ERROR: Unable to allocate memory.\n");
      exit(EXIT_FAILURE);
   }

   int pid = clone(fn, pchild_stack + (1024 * 1024), SIGCHLD, argv[1]);
   if ( pid < 0 ) {
        printf("ERROR: Unable to create the child process.\n");
        exit(EXIT_FAILURE);
   }

   wait(NULL);

   free(pchild_stack);

   printf("INFO: Child process terminated.\n");
}

From above code; we have created a function fn and place our mathematical table generation logic. This function fn is taking a single argument; we have declared this as per the guideline defined by clone(). So, we can pass this function to clone().

We have to create a stack for child process. So, we have allotted a memory using malloc function and release the memory using free once child process terminates. Observe that we pointed the pointer to point to topmost address of the stack memory.

We are calling clone() with SIGCHLD flag. So, we can keep calling process in wait state using wait() until the child process finishes.

We are taking an argument through main() and passing it to child function through clone(). Inside child function we are converting it to an integer; as our “Nth” mathematical table is based on int value.

Once you compile and run our program; it will display the below result. Remember that we have to pass an argument while running the application (hence ./a.out 7).

$ cc sample.c
$ ./a.out 7
Hello, World!

INFO: This code is running under child process.
7 * 1 = 7
7 * 2 = 14
7 * 3 = 21
7 * 4 = 28
7 * 5 = 35
7 * 6 = 42
7 * 7 = 49
7 * 8 = 56
7 * 9 = 63
7 * 10 = 70

INFO: Child process terminated.
$

// Malin

Leave a Reply