编辑
2023-10-25
linux
00
请注意,本文编写于 563 天前,最后修改于 563 天前,其中某些信息可能已经过时。

在Linux系统中,进程的标识符(PID)是用来唯一标识正在运行的进程的数字。在这些PID中,有一些特殊的PID值,分别是0、1和2。它们有特殊的含义,表示了系统中的一些重要进程。

  1. PID 0 - 调度进程(swapper): PID 0 是内核中的一个特殊进程,通常被称为“调度进程”或“swapper”。在早期的Unix系统中,调度进程用于在运行的进程之间切换,并将CPU时间片分配给不同的进程。在现代Linux系统中,PID 0不再表示一个实际运行的进程,而是用来标识系统初始化的内核线程。

  2. PID 1 - init进程: PID 1 是系统中的第一个真实进程,通常是init进程。init进程是Linux系统中的第一个用户空间进程,它是所有其他进程的父进程,因此被称为“祖先进程”。init进程负责启动和管理系统的各种服务和进程。然而,在现代Linux发行版中,init进程通常由更先进的init系统(如SysV init、Upstart、systemd等)代替。

  3. 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提供了多种功能,以便管理、控制和与进程交互。以下是一些常见的与进程相关的系统调用列表:

  1. 创建与执行进程

    • fork(): 创建一个新进程,称为子进程,它是调用进程的复制。
    • execve(): 在当前进程的上下文中执行一个新程序。
  2. 进程等待和终止

    • waitpid(): 等待一个特定的子进程终止,并获取其退出状态。
    • wait(): 等待任何子进程终止,并获取其退出状态。
    • exit(): 终止当前进程,返回退出状态给父进程。
  3. 进程间通信

    • pipe(): 创建一个管道,用于在父子进程或进程间进行双向通信。
    • shmget(), shmat(), shmdt(): 创建共享内存区域,允许进程在共享内存中交换数据。
    • msgget(), msgsnd(), msgrcv(), msgctl(): 创建消息队列,允许进程通过消息进行通信。
    • semget(), semop(), semctl(): 创建和操作信号量,用于进程间同步和互斥。
  4. 进程状态查询和控制

    • getpid(): 获取当前进程的ID。
    • getppid(): 获取父进程的ID。
    • getpgrp(), setpgid(): 获取或设置进程组ID。
    • nice(): 调整进程的优先级。
  5. 进程调度与优先级

    • sched_yield(): 放弃CPU,允许其他具有相同优先级的进程运行。
    • nice(): 调整进程的优先级。
  6. 进程信号

    • kill(): 向指定进程发送信号。
    • signal(), sigaction(): 设置信号处理程序。
  7. 进程时间和资源

    • 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号进程是所有内核线程的父进程。

原文链接:https://cloud.tencent.com/developer/article/1603977

本文作者:yowayimono

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!