Application vs Process vs Thread
The difference between these three concepts
The order in the title is important. Indeed an application is composed of one or more processes. A process is composed of one or more threads. That said let’s dig a bit deeper and see how applications, processes, and threads are created? What is the relationship between applications, processes, and threads? And finally how they are destroyed.
All the code in this article can be found here.
How to create an application? What happens when you double click on an executable or run it from a command-line terminal? Ultimately, what happens is a call to one of the exec(3) system calls. The main argument of this syscall is the path to an executable. The executable image will be loaded into the calling process in place of the old image. The below figure shows an example that loads a new application image, “echo”, into the current process.
Since calling exec(3) delete the old image of the process, it is generally not called directly. Instead, we first create a process that will execute exec(3) for us. The question remaining is then how to create a process? Well for that one ultimately need to call fork(). This syscall forks the current process into two (almost) identical processes. One of the differences is in the PID or process identifier. Each process will have one of its own. The below code shows an example where the function hello() is called directly and through a newly forked process.
To create a thread one can use pthread_create(3). This will create a thread within the current process. This thread will execute the function specified as a parameter at the moment of the creation of the thread. Finally, note that the clone(2) syscall can also be used to create a thread.
When creating a process using fork(2) there is a parent-child relationship between the 2 processes. The calling process is the parent and it keeps the original PID; while the new one will be the child and will be assigned a new PID. Thus, the processes of the systems are always connected through a tree-like structure. The below Figure shows an example of such a tree.
Using the examples in the previous section, we created similar three in C. The program creates three processes (using fork(2)). Then executes each of the examples seen so far: the process creation, the application creation, and the thread creation examples. The source code for creating such a tree can be found here.
A representation of the tree created by the example program can be obtained using the command pstree. This command prints by default the whole process tree. But can be limited to printing only a part of the tree using the “-p” option. For example, the output we obtained while running the command:
Processes are the glue of the system. They compose the application, contain one or more threads and form a tree-like structure. Then what happens when a process exits? Does the tree-like structure split into two? Especially if the exiting process is in the middle of the tree.
The answer is no. The structure is still kept by the system. To do this, the system re-parents any process that has lost its parent process to the “init" process: the first process of the system at the root of the tree. Init exits only when the system is to be shut down.
A thread exiting does not affect other threads. However when the last thread of a process exits. The entire process will also exit. For an application, we can say that it exited when all of its processes exited.