Linux clone(2) syscall

I’ve been trying out Linux clone(2). What follows is a small example I’ve assembled.

From the man page, “the main use of clone is to implement threads: multiple threads of control in a program that run concurrently in a shared memory space”. Also have in mind clone(2) is Linux-specific.

One example of a real-usage is this short program I wrote for running several prolog engines at the same time.

This is the main file:

cfs.c

#include
#include

#include

my_pred() {
FILE *fd = fopen("./teste", "w");
fwrite("ola", 1, sizeof("ola"), fd);
fclose(fd);
return TRUE;
}

thread() {
int retval;
Start_Prolog(0, 0); /* start prolog engine */
_exit(0);
}

main() {
void **child_stack;
child_stack = (void **) malloc(65536);
clone(thread, child_stack, CLONE_VM|CLONE_FILES, NULL);
}

In the main routine I just create one process with clone(2) but one could create as many as we would like of course. Unlike fork(2), clone allow 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. On this example I choosed to share the file descriptor table with the option CLONE_FILES. The CLONE_VM option will make the calling process and the child process run in the same memory space. This is good to make communication happen between the processes we will create and use.

The child process will begin by executing the function called ‘thread’ in this program. 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.

In the Makefile make sure to link with gprolog libraries. This is the Makefile I used:

Makefile

PLL=/usr/lib/gprolog-iso
LIBS=

all: cfs

cfs.o: cfs.c
gplc -c cfs.c

%.o: %.pl
gplc -c $+

cfs: cfs.o prolog.o
gcc -static -ggdb -Wall -o cfs \
$(PLL)/obj_begin.o \
$+ \
-L$(PLL) \
-lbips_fd \
-lengine_fd \
-lbips_pl \
$(PLL)/obj_end.o $(LIBS) -lengine_pl -llinedit -lm

clean:
rm -f *.o *~ cfs

And the prolog source code I tested this example with:

prolog.pl

:- foreign(my_pred, [fct_name(my_pred)]).
:- initialization(my_pred).

The ‘foreign’ call in prolog declares that a C function with that name exists.

This short example shows how to use clone(2) to create a multi-process program with gprolog. You could of course use it for creating processes that would run anykind of program in Linux.