进程原理基本概念

本文介绍了Linux进程的基本概念,包括进程的定义、四要素以及与线程的区别。详细讲解了进程的生命周期,从init进程开始,阐述了不同状态的转换。讨论了task_struct结构体在进程管理中的作用,以及进程优先级的分类。最后,提到了与进程相关的系统调用,如fork、vfork和clone,以及它们在创建和管理进程时的不同之处。

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

概念介绍

程序:指指令,数据以及组织形式描述
进程:不是运行单位,计算机已经运行程序,而是线程的容器。
进程的四要素:
1 有一段程序供其执行
2 有进程专用的系统堆栈空间
3 在内核有task_struct描述
4 进程有独立的存储空间,拥有专有的用户空间
有1,2,3缺少4,称为线程
若完全没有用户空间,称为内核线程
若共享用户空间,称为用户线程

生命周期

当linux启动的时候会启动0号进程init,然后其它的进程都是通过系统调用fork/clone来分离产生其它的所有进程。
进程的状态:运行态,就绪等待态,睡眠态(轻中重度),终止态,僵尸状态
在这里插入图片描述
在进程描述结构体中有一个voliate int state来标识进程是什么状态。无论何种状态的进程都会存在进程表中,内核中专门有进程表来进行管理所有的进程。

task_struct

内核结构体详细描述:
Linux 5.16.18 include/linux/sched.h文件中

struct task_struct {
   
   
#ifdef CONFIG_THREAD_INFO_IN_TASK
	// 每种体系结构下都实现的不同,task_struct是描述通用的,此描述不同的体系结构
	//与stack指针共同描述
	struct thread_info		thread_info;
#endif
	// 进程状态
	unsigned int			__state;
#ifdef CONFIG_PREEMPT_RT
	unsigned int			saved_state;
#endif
	randomized_struct_fields_start
	// 指向内核栈指针
	void				*stack;
	// 几个进程使用此结构
	refcount_t			usage;
	// 标识 ptrace系统调用,实现断点调试
	unsigned int			flags;
	unsigned int			ptrace;
#ifdef CONFIG_SMP  // 条件编译smp处理器
	int				on_cpu;
	struct __call_single_node	wake_entry;
	unsigned int			wakee_flips;
	unsigned long			wakee_flip_decay_ts;
	struct task_struct		*last_wakee;

	int				recent_used_cpu;
	int				wake_cpu;
#endif
	// 运行队列和进程调度相关的
	int				on_rq;

	int				prio;
	int				static_prio;
	int				normal_prio;
	unsigned int			rt_priority;

	struct sched_entity		se;
	struct sched_rt_entity		rt;
	struct sched_dl_entity		dl;
	const struct sched_class	*sched_class;

#ifdef CONFIG_SCHED_CORE
	struct rb_node			core_node;
	unsigned long			core_cookie;
	unsigned int			core_occupation;
#endif

#ifdef CONFIG_CGROUP_SCHED  
	// 线程组结构体链表
	struct task_group		*sched_task_group;
#endif

#ifdef CONFIG_UCLAMP_TASK
	struct uclamp_se		uclamp_req[UCLAMP_CNT];
	struct uclamp_se		uclamp[UCLAMP_CNT];
#endif
	struct sched_statistics         stats;
#ifdef CONFIG_PREEMPT_NOTIFIERS
	struct hlist_head		preempt_notifiers;
#endif

#ifdef CONFIG_BLK_DEV_IO_TRACE
	// 块设备io层的跟踪工具
	unsigned int			btrace_seq;
#endif
	//进程调度策略相关的字段
	unsigned int			policy;
	int				nr_cpus_allowed;
	const cpumask_t			*cpus_ptr;
	cpumask_t			*user_cpus_ptr;
	cpumask_t			cpus_mask;
	void				*migration_pending;
#ifdef CONFIG_SMP
	unsigned short			migration_disabled;
#endif
	unsigned short			migration_flags;

	// RCU同步原语
#ifdef CONFIG_PREEMPT_RCU
	int				rcu_read_lock_nesting;
	union rcu_special		rcu_read_unlock_special;
	struct list_head		rcu_node_entry;
	struct rcu_node			*rcu_blocked_node;
#endif /* #ifdef CONFIG_PREEMPT_RCU */

#ifdef CONFIG_TASKS_RCU
	unsigned long			rcu_tasks_nvcsw;
	u8				rcu_tasks_holdout;
	u8				rcu_tasks_idx;
	int				rcu_tasks_idle_cpu;
	struct list_head		rcu_tasks_holdout_list;
#endif /* #ifdef CONFIG_TASKS_RCU */

#ifdef CONFIG_TASKS_TRACE_RCU
	int				trc_reader_nesting;
	int				trc_ipi_to_cpu;
	union rcu_special		trc_reader_special;
	bool				trc_reader_checked;
	struct list_head		trc_holdout_list;
#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */

	struct sched_info		sched_info;
	// 进程架构链表
	struct list_head		tasks;
#ifdef CONFIG_SMP
	struct plist_node		pushable_tasks;
	struct rb_node			pushable_dl_tasks;
#endif
	// 进程管理进程的地址空间,独立4G  32位*86
	struct mm_struct		*mm;
	struct mm_struct		*active_mm;
	/* Per-thread vma caching: */
	struct vmacache			vmacache;
#ifdef SPLIT_RSS_COUNTING
	struct task_rss_stat		rss_stat;
#endif
	// 进程状态参数
	int				exit_state;
	int				exit_code;
	int				exit_signal;
	
<think>好的,我现在需要准备关于“进程的基本操作实验原理”的介绍。首先,我得回想一下进程相关的基础知识。进程是操作系统中的核心概念,它是程序的一次执行实例,拥有独立的内存空间和系统资源。在实验中,通常会涉及进程的创建、终止、切换等操作。 用户要求结构清晰,分步骤说明,所以我需要将内容组织成几个主要部分。首先可能得介绍进程基本概念,这样用户能有个基础理解。然后,实验通常会涉及哪些操作呢?比如创建进程、终止进程进程间通信、状态转换等。每个操作都需要解释其原理和涉及的机制。 接下来要考虑的是,如何具体实现这些操作。例如,在Unix/Linux系统中,创建进程通常使用fork()系统调用,而终止进程可能用exit()。进程切换涉及上下文保存和恢复,这部分需要说明CPU调度和内核的作用。 另外,可能需要提到进程控制块(PCB),因为这是操作系统管理进程的关键数据结构,存储了进程的状态、寄存器值等信息。实验可能通过模拟PCB来演示进程管理。 还要注意用户提到的格式要求,所有数学表达式和公式需要用正确的LaTeX格式。比如,在解释进程优先级调度时,如果有公式,需要用$$...$$包裹。同时,确保用中文回答,避免专业术语翻译错误。 需要验证每个操作的系统调用是否正确,例如fork()创建子进程,exec()替换进程映像,wait()等待子进程结束。这些系统调用的工作原理和相互关系需要清楚解释。 另外,进程间通信(IPC)的方法,如管道、消息队列、共享内存等,可能在实验中也会涉及,需要简要说明它们的原理和区别。 最后,实验原理部分可能需要结合具体的实验步骤或工具,比如在Linux环境下使用C语言编写代码,调用相关系统调用,观察进程的行为。这部分可以指导用户理解实验背后的操作系统机制。 需要确保内容准确,比如上下文切换的过程,涉及保存当前进程的状态到PCB,加载下一个进程的状态。这部分可能涉及内核调度器的运作,时间片轮转等调度算法。 可能还需要区分进程和线程,但用户的问题主要关注进程,所以可以略过线程部分,除非实验中有涉及。 检查是否有遗漏的关键点,比如进程的状态(就绪、运行、阻塞),状态转换图,以及这些状态如何通过操作系统调用来改变。 最后,组织这些内容,按照逻辑顺序分点说明,确保结构清晰,逐步引导用户理解进程操作的实验原理。</think>进程的基本操作是操作系统实验的核心内容,其原理涉及操作系统对进程生命周期的管理。以下从实验原理角度分步骤说明: ### 一、进程创建原理 1. **系统调用** 通过`fork()`系统调用创建子进程,其底层实现为: - 复制父进程的PCB(进程控制块) - 分配新的内存空间 - 设置子进程的PID(进程ID)和PPID(父进程ID) 2. **写时复制(Copy-On-Write)** $$ \text{物理内存} = \begin{cases} \text{共享父进程空间} & \text{未修改时} \\ \text{独立复制数据段} & \text{发生写入后} \end{cases} $$ ### 二、进程终止原理 1. **主动终止** 调用`exit()`触发: - 释放内存、打开的文件等资源 - 向父进程发送SIGCHLD信号 - 更新进程状态为**僵尸进程**直至父进程调用`wait()` 2. **强制终止** 通过`kill -9 PID`发送SIGKILL信号,内核直接清除进程控制块。 ### 三、进程切换原理 1. **上下文保存** 保存当前进程的: - 寄存器值(通过`struct pt_regs`) - 程序计数器(PC) - 堆栈指针(SP) 2. **调度算法** 常见时间片轮转调度: $$ \text{时间片长度} = \frac{\text{系统时钟周期}}{\text{优先级权重}} $$ ### 四、进程通信(IPC)原理 1. **管道通信** ```c int pipe(int fd[2]); // 创建缓冲区(默认大小4KB) ``` - 通过文件描述符`fd[0]`(读端)和`fd[1]`(写端)传输数据 2. **共享内存** ```c shmget() // 创建共享内存段 shmat() // 映射到进程地址空间 ``` - 直接访问同一物理内存区域,需配合信号量实现同步 ### 五、实验关键观测点 1. **进程树结构** 使用`pstree`命令验证父子进程关系: ``` init─┬─bash───fork_demo───child_process └─sshd ``` 2. **状态转换验证** 通过`ps aux`观察进程状态变化: - **R**(运行) - **S**(可中断睡眠) - **Z**(僵尸) ### 六、典型实验设计 1. **fork-exec组合** ```c if (fork() == 0) { execl("/bin/ls", "ls", NULL); // 替换子进程映像 } ``` 2. **优先级修改实验** ```c nice(5); // 调整进程优先级(Linux中-20~19范围) ``` **实验重点**:理解操作系统通过PCB管理进程的核心机制,掌握系统调用与内核态/用户态切换的关联。建议结合`strace`工具跟踪系统调用执行过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丰恒谷

你的鼓励是我最大创作动力!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值