1、進程的概念
進程是一個具有一定獨立功能的程序關於某個數據集合的一次運行活動。它是操作系統動態執行的基本單元,在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元。
2、輕量級進程
輕量級進程由clone()系統調用創建,參數是CLONE_VM,即與父進程是共享進程地址空間和系統資源。輕量級進程有自己獨立的用戶空間棧和內核空間棧,並且可以被linux操作系統像普通進程一樣被調度。
3、線程的概念
linux系統中用戶線程就是輕量級進程,因爲用戶線程就是由輕量級進程實現的。
4、進程的內存分佈
可執行程序文件必須被加載到內存中才能真正跑起來,程序被加載到內存中如上圖所示,標註出來的地址是虛擬地址,也就是用戶空間爲低位的3G,內核空間爲高位的1G。
.text區域:存放的是程序的代碼段,該區域只讀
.data區域:存放的是已經初始化的靜態或全局變量
.bss區域:存放的是未初始化的靜態或全局變量
heap區域:程序中的堆,程序中動態申請的內存就是在這個區域,會向上增長
map區域:加載的動態庫等會映射到這個區域,那麼這個區域會不會被heap或者stack覆蓋呢,有可能,但是系統會做好處理的。
stack區域:程序中的棧,程序執行過程中的函數調用相關的信息或者局部變量會放在這個區域,會向下增長。
heap和stack都加了隨機偏移,這樣做的目的是爲了安全吧,增加被攻擊的難度。5、線程的內存分佈
根據上面的瞭解我們知道線程(輕量級進程)有自己獨立的用戶空間棧和內核空間棧,所以在內存分佈多了獨立的棧,.text,.data,.bss和heap是共享的,包括打開的文件描述符等。用戶的空間棧大小默認是 8M,內核空間棧大小是 8k。
6、內核棧
linux-4.10/arch/arm/include/asm/thread_info.h
/*
46 * low level task data that entry.S needs immediate access to.
47 * __switch_to() assumes cpu_context follows immediately after cpu_domain.
48 */
49 struct thread_info {
50 unsigned long flags; /* low level flags */
51 int preempt_count; /* 0 => preemptable, <0 => bug */
52 mm_segment_t addr_limit; /* address limit */
53 struct task_struct *task; /* main task structure */
54 __u32 cpu; /* cpu */
55 __u32 cpu_domain; /* cpu domain */
56 struct cpu_context_save cpu_context; /* cpu context */
57 __u32 syscall; /* syscall number */
58 __u8 used_cp[16]; /* thread used copro */
59 unsigned long tp_value[2]; /* TLS registers */
60 #ifdef CONFIG_CRUNCH
61 struct crunch_state crunchstate;
62 #endif
63 union fp_state fpstate __attribute__((aligned(8)));
64 union vfp_state vfpstate;
65 #ifdef CONFIG_ARM_THUMBEE
66 unsigned long thumbee_state; /* ThumbEE Handler Base register */
67 #endif
68 };
linux-4.10/include/linux/sched.h
struct task_struct {
1512 #ifdef CONFIG_THREAD_INFO_IN_TASK
1513 /*
1514 * For reasons of header soup (see current_thread_info()), this
1515 * must be the first element of task_struct.
1516 */
1517 struct thread_info thread_info;
1518 #endif
1519 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
1520 void *stack;
1521 atomic_t usage;
1522 unsigned int flags; /* per process flags, defined below */
1523 unsigned int ptrace;
1524
1525 #ifdef CONFIG_SMP
1526 struct llist_node wake_entry;
1527 int on_cpu;
1528 #ifdef CONFIG_THREAD_INFO_IN_TASK
1529 unsigned int cpu; /* current CPU */
1530 #endif
1531 unsigned int wakee_flips;
1532 unsigned long wakee_flip_decay_ts;
1533 struct task_struct *last_wakee;
...
2009 };
task_sturce 就是進程(輕量級進程)對應的數據結構,linux kernel就是通過它來調度對應的進程。創建內核棧的時候會把thread_info 結構體放在棧底,使用棧的時候是從棧頂開始,往下增長。thread_info中的task指向對應的task_struct結構體,而task_stuct結構體中的stack是指向棧底的指針。