【进程 】

embedded/2025/2/23 22:14:20/

【进程】

  • 目录
      • 1. ELF格式程序与进程
      • 2. 进程的组织方式
      • 3. 进程的复刻(fork)
      • 4. 进程的状态

目录

1. ELF格式程序与进程

在Linux系统里,程序文件普遍采用ELF(Executable and Linkable Format)格式。这种格式的程序文件存储在硬盘上,处于静态。当程序被执行时,它会被载入内存,开启动态运行的进程之旅。具体来说,程序载入内存,就是把数据段、代码段等运行必不可少的资源复制到内存中。同时,系统会为这个正在运行的进程分配栈、堆等内存空间,让它从静态的程序转化为一个有生命力的、动态的实体。简单来讲,程序是静态存储在硬盘上的文件,进程则是程序在内存中运行的活动实例。
在这里插入图片描述

2. 进程的组织方式

在Linux操作系统中,除了系统启动时的初始进程,其余所有进程都源自一个父进程的复刻(fork)。这就如同人类家族繁衍,每个个体都由父母孕育而来。在整个Linux系统里,所有进程都起源于同一个初始进程,它们之间构成一棵倒置的进程树。通过pstree命令,我们能清晰地查看这些进程间的关系。例如:

shaseng@ubuntu:~$ pstree
systemd─┬─ModemManager───2*[{ModemManager}]├─VGAuthService├─accounts-daemon───2*[{accounts-daemon}]├─acpid├─avahi-daemon───avahi-daemon├─bluetoothd├─boltd───2*[{boltd}]├─colord───2*[{colord}]├─cron├─cups-browsed───2*[{cups-browsed}]├─cupsd├─2*[dbus-daemon]├─fcitx├─fcitx-dbus-watc├─firefox─┬─Privileged Cont───18*[{Privileged Cont}]│         ├─Web Content───15*[{Web Content}]│         ├─Web Content───14*[{Web Content}]│         ├─WebExtensions───16*[{WebExtensions}]│         └─58*[{firefox}]├─fwupd───4*[{fwupd}]├─gdm3─┬─gdm-session-wor─┬─gdm-x-session─┬─Xorg───{Xorg}│      │                 │               ├─gnome-session-b│      │                 │               └─2*[{gdm-x-session}]│      │                 └─2*[{gdm-session-wor}]│      └─2*[{gdm3}]├─gnome-keyring-d───3*[{gnome-keyring-d}]├─gsd-printer───2*[{gsd-printer}]├─ibus-x11───2*[{ibus-x11}]├─irqbalance───{irqbalance}├─2*[kerneloops]├─mosquitto├─networkd-dispat───{networkd-dispat}├─packagekitd───2*[{packagekitd}]├─polkitd───2*[{polkitd}]├─pulseaudio───2*[{pulseaudio}]├─python3───2*[{python3}]├─rsyslogd───3*[{rsyslogd}]├─rtkit-daemon───2*[{rtkit-daemon}]├─snapd───14*[{snapd}]├─sogoupinyinServ───4*[{sogoupinyinServ}]├─sogoupinyinServ───8*[{sogoupinyinServ}]├─sshd├─systemd─┬─(sd-pam)│         ├─at-spi-bus-laun─┬─dbus-daemon│         │                 └─3*[{at-spi-bus-laun}]│         ├─at-spi2-registr───2*[{at-spi2-registr}]│         ├─dbus-daemon│         ├─dconf-service───2*[{dconf-service}]│         ├─evolution-addre─┬─evolution-addre───5*[{evolution-addre}]│         │                 └─4*[{evolution-addre}]│         ├─evolution-calen─┬─evolution-calen───8*[{evolution-calen}]│         │                 └─4*[{evolution-calen}]│         ├─evolution-sourc───3*[{evolution-sourc}]│         ├─gnome-shell-cal───5*[{gnome-shell-cal}]│         ├─gnome-terminal-─┬─bash───pstree│         │                 └─3*[{gnome-terminal-}]│         ├─goa-daemon───3*[{goa-daemon}]│         ├─goa-identity-se───3*[{goa-identity-se}]│         ├─gvfs-afc-volume───3*[{gvfs-afc-volume}]│         ├─gvfs-goa-volume───2*[{gvfs-goa-volume}]│         ├─gvfs-gphoto2-vo───2*[{gvfs-gphoto2-vo}]│         ├─gvfs-mtp-volume───2*[{gvfs-mtp-volume}]│         ├─gvfs-udisks2-vo───2*[{gvfs-udisks2-vo}]│         ├─gvfsd─┬─gvfsd-http───2*[{gvfsd-http}]│         │       ├─gvfsd-trash───2*[{gvfsd-trash}]│         │       └─2*[{gvfsd}]│         ├─gvfsd-fuse───5*[{gvfsd-fuse}]│         └─ibus-portal───2*[{ibus-portal}]├─systemd-journal├─systemd-logind├─systemd-resolve├─systemd-timesyn───{systemd-timesyn}├─systemd-udevd├─udisksd───4*[{udisksd}]├─upowerd───2*[{upowerd}]├─vmhgfs-fuse───3*[{vmhgfs-fuse}]├─vmtoolsd├─vmtoolsd───{vmtoolsd}├─vmware-vmblock-───2*[{vmware-vmblock-}]├─whoopsie───2*[{whoopsie}]└─wpa_supplicant

从这个输出可以看出,最顶层的系统进程是systemd。它的诞生很特殊,在系统启动前,其身份信息就已存在于系统分区,系统启动时直接被复制到内存。而其他进程,都是systemd这个初始进程的直接或间接后代。

3. 进程的复刻(fork)

除了系统初始化进程,其他进程都是通过fork()函数复刻产生的。这个复刻过程类似细胞分裂。当一个进程复刻出一个子进程时,会将自身的大部分资源复制一份给子进程。

  • 父子进程创建之初相同的属性
    • 实际用户ID(UID)和组ID(GID),以及有效UID和GID。这些ID决定了进程对系统资源的访问权限,父子进程在创建时权限属性一致。
    • 所有环境变量。环境变量为进程提供运行时的配置信息,比如系统路径、语言设置等,子进程会继承父进程的环境变量。
    • 进程组ID和会话ID。进程组和会话ID用于进程间的管理和通信,父子进程同属一个进程组和会话。
    • 当前工作路径。工作路径决定了进程在文件系统中的操作位置,父子进程初始时工作路径相同。
    • 打开的文件。如果父进程打开了一些文件,子进程也会拥有相同的文件描述符,指向这些打开的文件。
    • 信号响应函数。信号是系统与进程通信的一种方式,父子进程对各种信号的响应方式在创建时是一样的。
    • 整个内存空间,包括栈、堆、数据段、代码段、标准IO的缓冲区等。虽然父子进程的内存空间在物理上是独立的,但内容在创建时完全一致。
  • 父子进程不同的属性
    • 进程号PID。每个进程都有唯一的PID,就像身份证号码,用于系统识别和管理进程,父子进程的PID必然不同。
    • 记录锁。如果父进程对某个文件加了记录锁,子进程不会继承这把锁,因为锁是针对特定进程的资源访问控制。
    • 挂起的信号。挂起的信号是等待进程响应的信号,子进程不会继承父进程那些“悬而未决”的信号。

4. 进程的状态

进程作为动态活动的实体,有着多种运行状态,从创建到回收经历不同阶段:

  • 所有进程(除系统初始进程systemd外)都有父进程。父进程通过调用fork()函数创建子进程,新创建的子进程拥有和父进程相同的执行代码、内存空间(虽然内容一样,但内存区域相互独立)等信息,此时子进程处于就绪态(TASK_RUNNING),表示它已经准备好运行,只要获得CPU资源就能执行。
  • 当进程退出时,不管是主动调用退出函数还是因错误等被动退出,都会进入僵尸态(EXIT_ZOMBIE)。在僵尸态下,进程无法运行,也不能被调度,但它所占据的系统资源尚未释放。僵尸态是进程结束的必经状态,在编程中无法避免,但要防止进程长时间处于僵尸态,因为这会浪费系统资源。
  • 僵尸态进程需要等待其父进程回收其资源后,才能转变为死亡态(EXIT_DEAD) ,死亡态的进程所有占据的系统资源可以被系统随时回收。

http://www.ppmy.cn/embedded/164689.html

相关文章

Linux-GlusterFS进阶分布式卷

文章目录 创建分布式卷创建复制卷 🏡作者主页:点击! 🤖Linux专栏:点击! ⏰️创作时间:2025年02月19日19点30分 创建分布式卷 同样是在Node1上进行的操作 分布式卷中的文件只能放在一个brick里…

私有化项目管理平台搭建:基于Leantime的实战经验分享

文章目录 前言1.关于Leantime2.本地部署Leantime3.Leantime简单实用4.安装内网穿透5.配置Leantime公网地址6. 配置固定公网地址 前言 本文主要介绍如何在本地Linux系统使用Docker部署Leantime,并结合cpolar内网穿透工具轻松实现随时随地查看浏览器页面,…

Webpack 基础入门

一、Webpack 是什么 Webpack 是一款现代 JavaScript 应用程序的静态模块打包工具。在 Web 开发中,我们的项目会包含各种类型的文件,如 JavaScript、CSS、图片等。Webpack 可以将这些文件打包成一个或多个文件,以便在浏览器中高效加载。它就像…

华为guass在dbever和springboot配置操作

下面记录华为guass在dbever和springboot配置操作,以备忘。 1、安装dbeaver-ce-23.2.0-x86_64-setup.exe和驱动程序 Download | DBeaver Community 2、配置高斯数据库驱动 3、新建数据库连接 4、操作指引 opengauss官方文档 https://docs-opengauss.osinfra.cn/zh…

qt for android release apk 手动签名方式

window 下,打开cmd 安装android sdk相关配置后,进行下列步骤 1.获取密钥, keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000根据提示步骤,输入密钥口令&…

[Android]使用WorkManager循环执行任务

使用WorkManager每隔30分钟执行一次任务 这种方式最低适配到SDK33 implementation("androidx.work:work-runtime-ktx:2.9.1") implementation("androidx.work:work-runtime-ktx:2.9.1")package com.mofsaas.box_n.ui import android.content.Context imp…

java 网络安全感知 网络安全学java

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 实验五 java网络编程及安全 实验内容 1.掌握Socket程序的编写;2.掌握密码技术的使用;3.设计安全传输…

【系统架构设计师】操作系统的分类

目录 1. 说明2. 批处理操作系统3. 分时操作系统4. 实时操作系统5. 网络操作系统6. 分布式操作系统7. 微型计算机操作系统8.嵌入式操作系统9.例题9.1 例题1 1. 说明 1.通常,操作系统可分为批处理操作系统、分时操作系统、实时操作系统、网络操作系统、分布式操作系统…