Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread(s) Memory Layout

I understand how a process memory layout looks like (Code, Data, Heap, Stack).

I do not understand, however, what exactly does a memory layout look like of a program with multiple threads.

After all, there is one stack for the process, so I would assume that all threads are sharing the same stack somehow.. But this does not seem right because every thread has its own stack, and threads are not guranteed to execute in the order they were called, so putting them one by one onto the process stack does not make a lot of sense to me.

I came across this picture on the net:

Threads memory layout

It appears here that every thread has its own stack, which makes sense, and also its own kernel stack.

Does that mean that I have (using the picture) 3 "processes" ? (Let's say that a process address space is 4GB, then 3 threads would be 12GB? I think not..)

I want to understand where each of the thread's stack sit in the memory.

I know all threads share Data & Code segments, so I would assume that either the Heap will contain the thread's stacks, or they will sit in Kernel space..

I would really like to know what happens..

Many appreciations.

like image 285
Tal Avatar asked Dec 08 '15 19:12

Tal


1 Answers

First of all, lets clearly separate both definitions. The process actually is a container of isolation which can hold system resources (like sockets, mutexes, etc.) and in which environment threads can execute. The process has no stack and does not receive CPU time (not schedulable). In contrast, the thread is a unit of scheduling performed by OS kernel. Thread periodically receives quant of CPU time to make progress and has a stack to store temporal data (local variables and return addresses).

The first note: virtual address space is a core part of the process abstraction. Each process has its own virtual address space and each virtual address space belongs only to one process. The second note: All threads running in the process share all resources of the process. Hence, all threads of the same process share the same address space. Every thread is able to access every byte of memory which another thread can access. One thread even can access local variables on the stack of another thread.

In the old UNIX, there was only one abstraction -- a process. But from the modern point of view, we could say that UNIX was stuck to 1-to-1 model (every process has one and only one thread). Due to this 1-to-1 model, UNIX was able to fix stack location in memory. Currently adopted 1-to-N model (multiple threads per single process) assumes that there is no such fixed stack location. Instead, OS kernel is responsible for locating space for the stack when it is requested to create the thread and for releasing of that space on thread termination. Furthermore, kernel even can reject the thread creation request if it will fail on the lookup of a free chunk of process virtual address space.

To maintain an illusion of uninterruptable thread execution. Kernel tracks for each thread its instruction and stack pointers. When kernel loads the thread on CPU (gives CPU time to the thread to execute) it loads special CPU registers with instruction and stack pointers maintained by the kernel for this particular thread. And when kernel unloads the thread from CPU it stores these pointers in the kernel memory. In such a way, the kernel creates an illusion that each thread has its own separate stack because thread itself does not need to deal with this stack pointer manipulations. In fact, we can say that each thread has its own part of address space logically assigned to him, but physically accessible to everybody in the process, but each thread has its own private stack pointer.

like image 139
ZarathustrA Avatar answered Sep 19 '22 19:09

ZarathustrA