linux 進程和線程簡介

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是指向棧底的指針。


發佈了62 篇原創文章 · 獲贊 37 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章