linux 进程和线程简介

本文详细介绍了进程与线程的概念,轻量级进程的特点及其实现方式,以及进程和线程在Linux系统中的内存分布情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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是指向栈底的指针。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值