Introduction to "Clone"
system call
clone() creates a new process, in a manner similar to
fork(2).
Unlike fork(2), clone() allows the child
process to share parts of its execution context with the calling process, such
as the memory space, the table of file descriptors, and the
table of signal handlers.
The main use of clone() is to implement
threads: multiple threads of control in a program that run concurrently in a
shared memory space.
When the child process is created with
clone(), it executes the function fn(arg). (This differs from fork, where
execution continues in the child from the point of the fork call.) The fn
argument is a pointer to a function that is called by the child process at the
beginning of its execution. The arg argument is passed to the fn
function.
When the fn(arg) function application
returns, the child process terminates. The integer returned by fn is the
exit code for the child process. The child process may also termi‐
nate explicitly by calling exit(2) or after receiving a fatal
signal.
The child_stack
argument specifies the location of the stack used by the
child process. Since the child and calling process may share memory, it
is not possible for the child process to execute in the same stack as the
calling process. The calling process must therefore set up memory space
for the child stack and pass a pointer to
this space to clone(). Stacks grow downward on
all processors that run Linux (except the HP PA processors), so child_stack
usually points to the topmost address of the memory space set up for the child
stack.
C program
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void *pchild_stack = NULL;
int fn(void *arg)
{
strcpy((char
*)pchild_stack, "aricent");
printf("I am
the child my pid :%d parent's parent pid : %d pchild_stack: %s \n"
,getpid() , getppid(), (char *)pchild_stack);
return 0;
}
void main(int argc, char *argv[])
{
pchild_stack =
malloc(1024 * 1024);
if ( pchild_stack
== NULL ) {
printf("ERROR: Unable to allocate memory.\n");
exit(EXIT_FAILURE);
}
strcpy((char *)pchild_stack, "google");
printf("I am
the parent my pid :%d parent's parent pid : %d pchild_stack: %s\n",
getpid() , getppid(), (char *)pchild_stack);
int pid = clone(fn, (char *)pchild_stack + (1024 * 1024), SIGCHLD, argv[1]);
if ( pid < 0 )
{
printf("ERROR: Unable to create the child process.\n");
exit(EXIT_FAILURE);
}
printf("INFO: Child process terminated.\n");
wait(NULL);
printf("I am the parent my pid :%d parent's parent pid : %d pchild_stack: %s\n",
getpid() , getppid(), (char *)pchild_stack);
free(pchild_stack);
pchild_stack =
NULL;
}
Output
Neelkanth_98$ ./a.out
I am the parent my pid :29371 parent's parent pid : 28022
pchild_stack: google
INFO: Child process terminated.
I am the child my pid :29372 parent's parent pid : 29371
pchild_stack: aricent
I am the parent my pid :29371 parent's parent pid : 28022
pchild_stack: google