当前位置: 首页 > news >正文

【操作系统原理】进程优先级与命令行参数、环境变量详解

头像
🎉博主首页: 有趣的中国人

🎉专栏首页: 操作系统原理

🎉其它专栏: C++初阶 | C++进阶 | 初阶数据结构

分割线动图

亲爱的小伙伴们,大家好!这篇文章我们把握 Linux 中三块“高频且基础”的知识:
进程优先级命令行参数(argc/argv)环境变量
它们决定了一个程序“如何被启动、如何被调度、在什么环境里运行”。
如果本文对你有启发,请点赞 👍、收藏 🌟、留言 📝 支持!

文章目录

    • @[toc]
  • 1. 进程优先级(Priority)
    • 1.1 本质与作用
    • 1.2 为什么要有优先级
    • 1.3 术语对照
    • 1.4 常用命令
    • 1.5 调度循环(示意)
  • 2. 命令行参数(argc / argv)
    • 2.1 main 的入口
    • 2.2 参数从哪里来(调用链)
    • 2.3 演示代码
  • 3. 环境变量(Environment Variables)
    • 3.1 概念速记
    • 3.2 常见环境变量
    • 3.3 `PATH` 的搜索与修改
    • 3.4 继承与写时拷贝(COW)
    • 3.5 C 接口常用法
  • 4. 内建命令 vs 外部命令
    • 4.1 区别一览
    • 4.2 如何辨别
    • 4.3 简化执行流程
  • 5. 实验清单(可直接跑)
    • 5.1 查看进程优先级
    • 5.2 PATH 与永久生效
    • 5.3 区分内建与外部
    • 5.4 程序中打印 `argv` 与 `environ`
  • 6. 常见疑问速记
  • 7. 小结

1. 进程优先级(Priority)


1.1 本质与作用

  • 在 Linux 中,每个进程对应一个 task_struct,其中保存调度相关字段(优先级、时间片等)。
  • 优先级越高,越容易获得 CPU 时间片;优先级越低,等待时间更长。

1.2 为什么要有优先级

  • CPU/内存/IO 等资源有限;任务数量多且类型不同(前台交互、后台服务、内核线程等)。
  • 通过优先级实现 公平 + 效率 的折中:关键任务优先,低优先级任务让步。

1.3 术语对照

名称说明
NI(nice 值)用户可调节的“偏移量”
PRI(动态优先级)调度器综合计算出的优先级
记忆口诀nice 越小越“凶”,优先级越高
  • nice 值范围:[-20, +19]
    • -20 → 最高优先级
    • +19 → 最低优先级
  • 普通用户:只能调低自身优先级(增大 nice 值)
  • root:可以把进程优先级调高(减小 nice 值)

1.4 常用命令

ps -al                 # 查看 PRI/NI 等字段
top                    # 实时查看;在 top 界面按 r 修改某 PID 的 nice
renice -n 5 PID        # 修改已存在进程的 nice 值
sudo nice -n -5 ./a.out  # 更高优先级启动新程序(需 root)

1.5 调度循环(示意)

回到就绪队列等待
调度器按优先级挑选进程
分配时间片运行
时间片耗尽或被更高优先级抢占

2. 命令行参数(argc / argv)


2.1 main 的入口

int main(int argc, char *argv[])
  • argc:参数个数
  • argv[]:参数数组(argv[0] 通常是程序名)

2.2 参数从哪里来(调用链)

  1. 用户在 bash 输入命令;
  2. bash 解析字符串并构建 argv[]
  3. fork() 创建子进程;
  4. 子进程调用 execve(path, argv, envp)
  5. 内核加载可执行文件,新程序从 main(argc, argv, envp) 开始执行。

2.3 演示代码

#include <stdio.h>
int main(int argc, char *argv[]) {for (int i = 0; i < argc; i++) {printf("argv[%d] = %s\\n", i, argv[i]);}return 0;
}

示例

$ ./a.out linux kernel study
argv[0] = ./a.out
argv[1] = linux
argv[2] = kernel
argv[3] = study

3. 环境变量(Environment Variables)


3.1 概念速记

  • 环境变量是进程的运行时配置表(键值对)。
  • 每个进程都有自己的副本,默认从父进程继承

3.2 常见环境变量

变量名说明
PATH查找可执行文件的目录列表
HOME用户主目录
PWD当前工作目录
SHELL当前使用的 Shell 程序
HISTSIZEbash 历史条数

3.3 PATH 的搜索与修改

  • 执行命令时,bash 会按 PATH 中的目录顺序搜索可执行文件。
  • 临时修改(仅当前终端有效):
export PATH="$PATH:/usr/local/mybin"
  • 永久生效(下次终端也有效):把上面这行写入 ~/.bashrc(或登录 Shell 的 ~/.bash_profile),然后:
source ~/.bashrc

3.4 继承与写时拷贝(COW)

  • fork() 后,子进程继承父进程的环境变量副本(COW:按需复制)。
  • execve() 执行新程序时,默认沿用当前环境(也可以传入自定义 envp)。
graph LR
A[父进程 bash] -->|fork| B[子进程:共享只读页]
B -->|写环境时才复制| C[按需复制]
B -->|execve 继承/替换| D[新程序:envp 可自定义]

3.5 C 接口常用法

#include <stdio.h>
#include <stdlib.h>int main() {printf("HOME = %s\\n", getenv("HOME"));setenv("TEST_VAR", "hello", 1); // 覆盖printf("TEST_VAR = %s\\n", getenv("TEST_VAR"));return 0;
}

一次性打印全部环境变量

#include <stdio.h>
extern char **environ;
int main() {for (int i = 0; environ[i]; ++i) puts(environ[i]);return 0;
}

4. 内建命令 vs 外部命令


4.1 区别一览

类型典型示例是否创建子进程为什么
内建命令cdexportaliasecho(也可能有外部版)在 bash 进程内直接执行,能修改当前 Shell 状态(例如 cd 改变目录)
外部命令/usr/bin/echo/usr/bin/pwd通过 fork + exec 启动新程序

关键点:如果 cd 作为外部程序运行,就无法改变当前终端的工作目录,所以它必须是内建。

4.2 如何辨别

type -a cd
type -a echo
type -a pwd
  • 显示 is a shell builtin → 内建;
  • 显示路径如 /usr/bin/echo → 外部程序(有些命令内建与外部版本并存)。

4.3 简化执行流程

bash 接收命令
内建吗?
在当前 bash 进程里执行函数
fork 子进程
execve 加载外部程序
运行完毕返回父进程

5. 实验清单(可直接跑)


5.1 查看进程优先级

ps -al | head
top                  # 在 top 界面按 r 可修改某个进程的 nice

5.2 PATH 与永久生效

echo "$PATH"
export PATH="$PATH:$HOME/bin"   # 临时
echo 'export PATH="$PATH:$HOME/bin"' >> ~/.bashrc
source ~/.bashrc                # 让当前会话立即生效

5.3 区分内建与外部

type -a echo
type -a pwd
type -a cd

5.4 程序中打印 argvenviron

#include <stdio.h>
extern char **environ;
int main(int argc, char *argv[]) {puts("[argv]");for (int i = 0; i < argc; ++i) printf("argv[%d]=%s\\n", i, argv[i]);puts("[environ]");for (int i = 0; environ[i]; ++i) puts(environ[i]);return 0;
}

6. 常见疑问速记


  • Q:为什么我不显式给子进程传环境变量,子进程也有?
    A:fork 会继承父进程的环境(COW),execvp 默认沿用当前进程的环境,所以能看到与 bash 相同的变量。

  • Q:修改 PATH 后,新开终端又恢复?
    A:你只在当前 Shell 做了临时修改。写入 ~/.bashrc(或登录 Shell 的 ~/.bash_profile)并 source 才会对新会话生效。

  • Q:为什么 echo/pwd 既是内建又存在 /usr/bin/echo
    A:为了兼容不同 Shell、脚本或最小化环境。type -a echo 可以查看优先级顺序;通常优先使用内建版本。

  • Q:cd 参数是否合法怎么判断?
    A:在 C 程序中检查 chdir(path) 返回值是否为 -1;在 Shell 里可用 [[ -d "$1" ]] 判断目录是否存在。

  • Q:普通用户能把进程优先级调高吗?
    A:不能。普通用户只能降低自身优先级(增大 nice 值);提升优先级需要 root


7. 小结


  • 优先级(PRI + nice) 决定进程拿到 CPU 的速度与频率;
  • 命令行参数(argc/argv) 由 bash 解析并通过 execve 传给 main
  • 环境变量 通过 fork 继承,execve 继续使用或替换;
  • 内建命令 在 bash 内执行以便修改当前会话状态,外部命令则走 fork+exec

把这四块打通,你就掌握了“一个命令如何被解析、加载与调度”的全流程。欢迎在评论区补充你的实验结果或遇到的问题!

http://www.dtcms.com/a/592883.html

相关文章:

  • 【深度学习新浪潮】扩散模型中,VAE潜空间正则化如何为生成带来帮助?
  • 从零学习Node.js框架Koa 【四】Koa 与数据库(MySQL)连接,实现CRUD操作
  • Zotero在代理模式下无法同步问题
  • LeetCode(python)——438.找到字符串中所有字母异位词
  • 解决添加asp.net网站报错请添加 MIME 映射
  • 浙江省工程建设管理协会网站常州小程序开发公司
  • ASP vs ASP.NET vs ASP.NET Core:三代微软 Web 技术核心区别解析
  • 【项目设计】基于正倒排索引的Boost搜索引擎
  • 建网站需要几程序员关键词网站优化平台
  • 深圳网站建设方案书做sns网站需要什么
  • C语言常见推理题
  • leetcode 3542. 将所有元素变为 0 的最少操作次数 中等
  • 一文掌握,sward安装与配置
  • Supabase 开源 BaaS 平台的技术内核与实践指南
  • YOLOv5+DeepSORT目标检测
  • 通过Prometheus对GPU集群进行监控以及搭建(小型集群)
  • 【datawhale】Agentic AI学习笔记
  • 江苏国龙翔建设公司网站找工作网站建设
  • 网站建设及在线界面设计
  • Aloha浏览器 7.10.1 |私人浏览器,极速上网,资源嗅探
  • 多Agent协同-详解
  • Spring Boot 数据库操作实战:MyBatis 让 CRUD 像 “查奶茶库存” 一样简单
  • 电脑五笔打字入门口诀:3天学会五笔打字拆字
  • 自动驾驶中的B样条轨迹及B样条<->贝塞尔转换实现避障
  • 南阳市做网站网站开发是什么专业百度
  • 做外包的网站有哪些问题最好玩的网站
  • 阿尔及尔至广州直飞航线成功首航
  • 太原网站建设找山西云起时北京做网站优化的公司
  • 价值优先,敏捷致胜:超越“数据治理优先”的AI实施新范式
  • 2025年下半年软考高级系统架构师题目和答案