Concept of Thread

Table of Content

Experimental Environment

We use a Debian Linux system on an Oracle Virtual Machine as our experimental environment.

Thread via clone

Loosely speaking, Linux has two system calls fork and clone with which we can create new processes. To contrast the behavior the two system calls, we can take a closer look at the manual pages of the system calls. The manual page of clone states

By contrast with fork(2), these system calls provide more precise control over what pieces of execution context are shared between the calling process and the child process.

The manual page goes on and discusses a list flags with which we assert the control over process creation via clone. A flag of interest is CLONE_VM. The manual page explains it as follows:

CLONE_VM (since Linux 2.0)

If CLONE_VM is set, the calling process and the child process run in the same memory space. In particular, memory writes per‐ formed by the calling process or by the child process are also visible in the other process. Moreover, any memory mapping or unmapping performed with mmap(2) or munmap(2) by the child or calling process also affects the other process.

If CLONE_VM is not set, the child process runs in a separate copy of the memory space of the calling process at the time of the clone call. Memory writes or file mappings/unmappings per‐ formed by one of the processes do not affect the other, as with fork(2).

If the CLONE_VM flag is specified and the CLONE_VM flag is not specified, then any alternate signal stack that was established by sigaltstack(2) is cleared in the child process.

To understand this, we write the following programs in two versions where the two versions differ by with and without the flag. We call these two the process version and the thread version.

The difference of the two versions are the value of the flags passed to the clone system call (strictly speaking, a Lib C wrapper).

$ diff cloneme.c clonemevm.c
38c38
<   pid = clone(change_print_var, stack_top, 0, NULL);
---
>   pid = clone(change_print_var, stack_top, CLONE_VM, NULL);
$

What the effect of the difference? We can compare the outputs of the two versions:

$ ./cloneme
Parent[pid=1893]: state initialized to 0
Parent[pid = 1893]: clone returned 1894
Child[pid=1894]: change_print_var: change state from 0 to -1
./Parent[pid = 1893]: after child exited: state = 0
$ ./clonemevm
Parent[pid=1895]: state initialized to 0
Parent[pid = 1895]: clone returned 1896
Child[pid=1896]: change_print_var: change state from 0 to -1
Parent[pid = 1895]: after child exited: state = -1
$

Questions

Complete the experiment and answer the questions:

  1. What is the difference in the outputs of the two versions?
  2. What is the difference between thread and process?
  3. What is the benefits of thread, and what is the benefits of process? Any disadvantages?