在Linux系统中,进程的标识符(PID)是用来唯一标识正在运行的进程的数字。在这些PID中,有一些特殊的PID值,分别是0、1和2。它们有特殊的含义,表示了系统中的一些重要进程。
PID 0 - 调度进程(swapper): PID 0 是内核中的一个特殊进程,通常被称为“调度进程”或“swapper”。在早期的Unix系统中,调度进程用于在运行的进程之间切换,并将CPU时间片分配给不同的进程。在现代Linux系统中,PID 0不再表示一个实际运行的进程,而是用来标识系统初始化的内核线程。
PID 1 - init进程:
PID 1 是系统中的第一个真实进程,通常是init
进程。init
进程是Linux系统中的第一个用户空间进程,它是所有其他进程的父进程,因此被称为“祖先进程”。init
进程负责启动和管理系统的各种服务和进程。然而,在现代Linux发行版中,init
进程通常由更先进的init系统(如SysV init、Upstart、systemd等)代替。
PID 2 - kthreadd进程:
PID 2 是内核线程kthreadd
的PID。kthreadd
是Linux内核中的一个线程,负责创建和管理内核线程,这些线程用于执行不同的内核任务。kthreadd
是内核的一部分,它帮助管理其他内核线程的创建和终止。
总结: PID 0、1和2是Linux系统中的特殊PID,具有特殊的含义。PID 0是调度进程,用于系统初始化。PID 1是init进程或其等效的init系统,是用户空间的第一个进程,负责启动和管理其他进程。PID 2是kthreadd进程,负责管理内核线程。这些特殊PID在Linux系统的运行中发挥着重要的作用。
当涉及与进程相关的系统调用时,Linux提供了多种功能,以便管理、控制和与进程交互。以下是一些常见的与进程相关的系统调用列表:
创建与执行进程:
fork()
: 创建一个新进程,称为子进程,它是调用进程的复制。execve()
: 在当前进程的上下文中执行一个新程序。进程等待和终止:
waitpid()
: 等待一个特定的子进程终止,并获取其退出状态。wait()
: 等待任何子进程终止,并获取其退出状态。exit()
: 终止当前进程,返回退出状态给父进程。进程间通信:
pipe()
: 创建一个管道,用于在父子进程或进程间进行双向通信。shmget()
, shmat()
, shmdt()
: 创建共享内存区域,允许进程在共享内存中交换数据。msgget()
, msgsnd()
, msgrcv()
, msgctl()
: 创建消息队列,允许进程通过消息进行通信。semget()
, semop()
, semctl()
: 创建和操作信号量,用于进程间同步和互斥。进程状态查询和控制:
getpid()
: 获取当前进程的ID。getppid()
: 获取父进程的ID。getpgrp()
, setpgid()
: 获取或设置进程组ID。nice()
: 调整进程的优先级。进程调度与优先级:
sched_yield()
: 放弃CPU,允许其他具有相同优先级的进程运行。nice()
: 调整进程的优先级。进程信号:
kill()
: 向指定进程发送信号。signal()
, sigaction()
: 设置信号处理程序。进程时间和资源:
times()
: 获取进程和子进程的累计CPU时间。getrusage()
: 获取进程或子进程的资源使用情况。这只是一部分与进程相关的系统调用列表,还有其他更多的系统调用可以用于进程管理和控制。每个系统调用都有其特定的用途和参数
(1)inin进程会调用prepare_namespace()函数去挂载根文件系统,根文件系统的存储位置由bootcmdline指定(例如:root=/dev/mmcblk0p2);
(2)挂载上根文件系统后,去查找应用层的初始化函数,应用层的初始化函数也是通过bootcmdline指定(例如:init=/linuxrc);
(3)init进程调用run_init_process()函数去执行应用层的初始化函数,然后init进程就从内核态转变成用户态;
(4)打开控制台"/dev/console",此时得到文件描述符(因为是打开的第一个文件,文件描述符是0),然后将文件描述符赋值两遍,得到文件描述符0、1、2,也就是标准输出、标准输入、标准出错。
(5)init进程构建了交互界面,启动了login进程、命令行进程、shell进程
(1)init进程是通过kernel_thread()函数创建,刚开始是内核线程,当执行应用层的初始化函数后就变成用户态的线程,并且这个过程是不可逆的, init进程将一直是用户态线程;
(2)init进程是其他用户态线程的祖宗进程,其他用户态线程都是init进程直接\间接创建; 原文链接:https://blog.csdn.net/weixin_42031299/article/details/122444282
当系统中所有的进程起来后,0号进程也就蜕化为idle进程,当一个core上没有任务可运行时就会去运行idle进程。一旦运行idle进程则此core就可以进入低功耗模式了,在ARM上就是WFI。
我们本节重点关注是0号进程是如何启动的。在linux内核中为0号进程专门定义了一个静态的task_struct的结构,称为init_task。
linux启动的第一个进程是0号进程,是静态创建的
在0号进程启动后会接连创建两个进程,分别是1号进程和2和进程。
1号进程最终会去调用可init可执行文件,init进程最终会去创建所有的应用进程。
2号进程会在内核中负责创建所有的内核线程
所以说0号进程是1号和2号进程的父进程;1号进程是所有用户态进程的父进程;2号进程是所有内核线程的父进程。
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!