【Linux】环境变量与进程优先级
文章目录
- 🎪 进程优先级
- 🚀1.孤儿进程
- 🚀2.优先级查看
- 🚀3.优先级修改
- 🎪 环境变量
- 🚀1.常见环境变量
- 🚀2.环境变量获取
- 🚀3.main中的命令行参数
🎪 进程优先级
每个进程都有相应的优先级,优先级决定它何时运行和接收多少 CPU 时间。最终的优先级共 32 级,是从 0 到 31 的数值,称为基本优先级别(Base Priority
Level)。
🚀1.孤儿进程
在父子进程的问题中,父进程如果比子进程先退出,那么子进程退出后将进入Z状态,那么它的资源又该由谁来回收呢?如果没有了父进程,子进程退出一直卡在僵尸状态会造成内存泄露。那么OS该怎么处理呢?
myproc.c
#include <stdio.h>
#include <unistd.h>int main()
{pid_t id = fork();if (id == 0){while (1){printf("我是子进程:pid:%d,ppid:%d\n", getpid(), getppid());sleep(1);}}else{int cnt = 10;while (1){printf("我是父进程:pid:%d,ppid: %d\n", getpid(), getppid());sleep(1);if (cnt-- <= 0) break;}}return 0;
}
Makefile
myproc:myproc.cgcc -o $@ $^
.PHONY:clean
clean:rm -f myproc
这里我们运行myproc后10s后父进程会自动退出,这里我们用shell脚本语言便于观察一下子进程的情况:
while :; do ps ajx | head -1 && ps -ajx | grep myproc | grep -v grep; sleep 1; echo "-----------"; done

我们发现父进程运行结束后并没有进入僵尸状态,而是被它的父进程bash回收了,而子进程的父进程变成了1, 这个PID为1的就是操作系统本身,也就是说父进程退出后,子进程会被OS自动领养称为后台进程——即孤儿进程
🚀2.优先级查看
- UID : 代表执行者的身份
- PID : 代表这个进程的代号
- PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
- PRI :代表这个进程可被执行的优先级,其值越小越早被执行
- NI :代表这个进程的nice(修正)值

我们创建进程默认优先级是80,区间是[60,99].默认修正值是0,区间是[-20,19],其中当前优先级 = 默认优先级 - nice值:即PRI(new)=PRI(old)+nice
🚀3.优先级修改
当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行,所以,调整进程优先级,在Linux下,就是调整进程nice值
命令:
top+r+PID+NI
功能:调整进程NI值(root下)
调整进程4193优先级为85,即修改nice值为5.


🎪 环境变量
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
- 按生命周期分:
永久的:在环境变量脚本文件中配置,用户每次登录时会自动执行这些脚本,相当于永久生效。
临时的:用户利用export命令,在当前终端下声明环境变量,关闭Shell终端失效。 - 按作用域分:
系统环境变量:公共的,对全部的用户都生效。
用户环境变量:用户私有的、自定义的个性化设置,只对该用户生效。

🚀1.常见环境变量
PATH: 指定命令的搜索路径HOME: 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)SHELL: 当前Shell,它的值通常是/bin/bash
命令:
echo $NAME
功能:查看环境变量内容
我们可以观察到PATH环境变量内容如下:此路径代表各个命令的搜索路径。

我们之前说过Linux的基本命令本质上也是一个可执行程序,跟我们自己的程序本质上是一样的,那么我们自己的程序为什么要带./才能执行呢,不能像指令一样直接运行吗?当然可以,我们将它添加进系统的环境变量中即可.
pro2.c
#include <stdio.h>
#include <unistd.h>int main()
{printf("hello world\n");printf("hello world\n");printf("hello world\n");printf("hello world\n");printf("hello world\n");return 0;
}
我们将该程序对应的路径添加进PATH环境变量里边,即export $PATH = /home/ljk/linux/107c++work/work10

添加进去后,我们的程序确实可以向指令一样运行了,但是在PTAH路径下的指令都找不到路径无法运行了,我们相当于直接把系统路径替换了成了我们的路径,那怎么办呢?我们只需要把我们的OS重启即可恢复正常.我们要的是追加而不是替换。
执行命令:export PATH=$PATH:/home/ljk/linux/107c++work/work10

此时便完成了我们路径的追加.
除了添加环境变量,我们还可以直接添加程序到路径/user/bin/目录下也可以把我们自己的程序当命令来执行

🚀2.环境变量获取
环境变量相关指令:
echo: 显示某个环境变量值export: 设置一个新的环境变量env: 显示所有环境变量unset: 清除环境变量set: 显示本地定义的shell变量和环境变量
我们可以使用env命令来查看当前进程的环境变量:

在最新的C99标准中,入口函数main函数还可以这样定义:
int main( int argc, char *argv[], char* envp[]) /* 带参数形式 */{...return 0;}
envp数组是一个字符指针的数组,这个数组的每一个元素是指向一个环境变量的字符指针。我们就可以通过遍历envp数组来实现对进程环境变量的获取:
pro3.c
#include <stdio.h>
#include <unistd.h>int main(int argc, char* argv[], char* envp[])
{int i = 0;for (i = 0; envp[i]; i++){printf("envp[%d]->%s\n", i, envp[i]);}return 0;
}

除了通过命令行参数获取,我们还可以通过第三方变量environ获取
pro4.c
#include <stdio.h>int main(int argc, char* argv[])
{extern char** environ;int i = 0;for (; environ[i]; i++){printf("environ[%d] -> %s\n", i, environ[i]);}return 0;
}

我们可以用以上方法获取环境变量,但是不推荐,因为使用场景不符合实际情况,我们通常会获取单一环境变量,我们可以用函数getenv("NAME")获取我们需要的环境变量.我们先来查一下该函数:

该函数需要传入参数环境变量名,返回值是环境变量内容
pro5.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>int main()
{char* pwd = getenv("PWD");if (pwd == NULL) perror("getenv");else printf("PWD: %s\n", pwd);char* user = getenv("USER");if (user == NULL) perror("getenv");else printf("USER: %s\n", user);return 0;
}

注意:
- 环境变量本质上就是内存级的一张表,这张表在用户登录系统的时候,进行给特定用户形成属于自己的环境变量表
- 环境变量中的每一个,都有自己的用途:有的进行路径查找,有的进行身份认证,有的进行动态库查找,有的用来确认当前路径
- 每个环境变量都有自己的应用场景,且每个元素都是k-v映射的
我们的envp数组实际上就是存放的环境变量表的内容,environ变量也是,而函数getenv()也是在环境变量表中查找的.
除此之外,我们还可以利用环境变量为自己的程序设置权限:
pro6.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>int main()
{char* user = getenv("USER");if (strcmp(user, "ljk") == 0){printf("程序已执行...\n");}else{printf("执行错误,当前用户 %s 为非法用户\n", user);}return 0;
}

环境变量通常具有全局属性,可以被相关的子进程继承,我们自己导入的环境变量也是如此:
pro7.c
#include <stdio.h>
#include <stdlib.h>int main()
{char* myenv = getenv("Myenv");if (myenv != NULL){printf("Myenv: %s\n", myenv);}return 0;
}
我们运行后发现未找到环境变量,我们再继续执行export Myenv=“hello world”,这时在运行程序,发现可以找到该环境变量:

说明:环境变量具有全局性,是可以被子进程继承的
🚀3.main中的命令行参数
我们讨论了main函数中的第三个参数,前两个参数是啥呢?
- argc表示数组argv元素个数
- argv表示命令行参数,需要我们自己传入
pro8.c
#include <stdio.h>int main(int argc, int* argv[])
{for (int i = 0; i < argc; i++){printf("argv[%d]->%s\n", i, argv[i]);}return 0;
}

我们就可以用条件判断传入的参数,从而实现不同的功能。
pro9.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>void Usage(const char *name)
{printf("\nUsage: %s -[a|b|c]\n\n", name);exit(0);
}
int main(int argc, int* argv[])
{if (argc != 2) Usage(argv[0]);if (strcmp(argv[1], "-a") == 0) printf("打印当前目录下的文件名\n");else if (strcmp(argv[1], "-b") == 0) printf("打印当前目录下文件的详细信息\n");else if (strcmp(argv[1], "-c") == 0) printf("打印当前目录下的文件名(含隐藏文件)\n");else printf("其它功能,敬请期待\n");}

这种通过选项来改变输出内容是不是很熟悉,没错,我们的命令后面带的选项本质上也是传入的命令行参数实现不同的功能
相关文章:
【Linux】环境变量与进程优先级
文章目录🎪 进程优先级🚀1.孤儿进程🚀2.优先级查看🚀3.优先级修改🎪 环境变量🚀1.常见环境变量🚀2.环境变量获取🚀3.main中的命令行参数🎪 进程优先级 每个进程都有相应…...
RocketMQ5.0.0的Broker主从同步机制
目录 一、主从同步工作原理 1. 主从配置 2. 启动HA 二、主从同步实现机制 1. 从Broker发送连接事件 2. 主Broker接收连接事件 3. 从Broker反馈复制进度 4. ReadSocketService线程读取从Broker复制进度 5. WriteSocketService传输同步消息 6. GroupTransferService线程…...
深度学习论文: EdgeYOLO: An Edge-Real-Time Object Detector及其PyTorch实现
深度学习论文: EdgeYOLO: An Edge-Real-Time Object Detector及其PyTorch实现 EdgeYOLO: An Edge-Real-Time Object Detector PDF: https://arxiv.org/pdf/2302.07483.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https://github.com/shangli…...
如何做好APP性能测试?
随着智能化生活的推进,我们生活中不可避免的要用到很多程序app。有的APP性能使用感很好,用户都愿意下载使用,而有的APP总是出现卡顿或网络延迟的情况,那必然就降低了用户的好感。所以APP性能测试对于软件开发方来说至关重要&#…...
Hive窗口函数
概述 窗口函数(window functions)也叫开窗函数、OLAP函数。 如果函数具有over子句,则它是窗口函数 窗口函数可以简单地解释为类似于聚合函数的计算函数,但是通过group by 子句组合的 常规聚合会隐藏正在聚合的各个…...
C++学习笔记(1):在默认构造函数内部使用带参数的构造函数
题目以下代码的输出是不是0:#include <unordered_map> #include <iostream>using namespace std;struct CLS{int i;CLS(int i_) :i(i_){}CLS(){CLS(0);} };int main(){CLS obj;std::cout << obj.i << endl;return 0; }结果-858993460为什么…...
Android面试题_安卓面经(23/30)设计模式源码案例
系列专栏: 《150道安卓常见面试题全解析》 安卓专栏目录见帖子 : 安卓面经_anroid面经_150道安卓基础面试题全解析 安卓系统Framework面经专栏:《Android系统Framework面试题解析大全》 安卓系统Framework面经目录详情:Android系统面经_Framework开发面经_150道面试题答案解…...
Dubbo性能调优参数以及原理
Dubbo作为一个服务治理框架,功能相对来说比较完善,性能也挺不错。但很多同学在使用dubbo的时候,只是简单的参考官方说明进行配置和应用,并没有过多的去思考一些关键参数的意义,最终做出来的效果总是差强人意,接下来我们…...
vue3全家桶之vuex和pinia持久化存储基础(二)
一.vuex数据持久化存储 这里使用的是vuex4.1.0版本,和之前的vuex3一样,数据持久化存储方案也使用 vuex-persistedstate,版本是最新的安装版本,当前可下载依赖包版本4.1.0,接下来在vue3项中安装和使用: 安装vuex-persistedstate npm i vuex-persisteds…...
LAMP架构与搭建论坛
目录 1、LAMP架构简述 2、各组件作用 3、构建LAMP平台 1.编译安装Apache httpd服务 2.编译安装mysql 3.编译安装php 4.搭建一个论坛 1、LAMP架构简述 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整台系统和相关软件,能够提供动…...
代码随想录 || 回溯算法93 78 90
Day2493.复原IP地址力扣题目链接给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 . 分隔。例如&#…...
界面组件Kendo UI for Angular——让网格数据信息显示更全面
Kendo UI致力于新的开发,来满足不断变化的需求,通过React框架的Kendo UI JavaScript封装来支持React Javascript框架。Kendo UI for Angular是专用于Angular开发的专业级Angular组件,telerik致力于提供纯粹的高性能Angular UI组件,…...
【Linux】进程状态|优先级|进程切换|环境变量
文章目录1. 运行队列和运行状态2. 进程状态3. 两种特殊的进程僵尸进程孤儿进程4. 进程优先级5. 进程切换进程特性进程切换6. 环境变量的基本概念7. PATH环境变量8. 设置和获取环境变量9. 命令行参数1. 运行队列和运行状态 💕 运行队列: 进程是如何在CP…...
合宙Air780E|FTP|内网穿透|命令测试|LuatOS-SOC接口|官方demo|学习(18):FTP命令及应用
1、FTP服务器准备 本机为win11系统,利用IIS搭建FTP服务器。 搭建方式可参考博文:windows系统搭建FTP服务器教程 windows系统搭建FTP服务器教程_程序员路遥的博客-CSDN博客_windows服务器安装ftp 设置完成后,测试FTP(已正常访问…...
大规模 IoT 边缘容器集群管理的几种架构-4-Kubeedge
前文回顾 大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介大规模 IoT 边缘容器集群管理的几种架构-1-RancherK3s大规模 IoT 边缘容器集群管理的几种架构-2-HashiCorp 解决方案 Nomad大规模 IoT 边缘容器集群管理的几种架构-3-Portainer 📚️Reference…...
Spring底层核心原理解析
Spring简介 ClassPathXmlApplicationContext context new classPathXmlApplicationContext("spring.xml"); UserService userService (UserService) context.getBean("userService"); userService.test();上面一段代码是我们开始学习spring时看到的&…...
OpenStack手动分布式部署Glance【Queens版】
目录 Glance简介 1、登录数据库配置(在controller执行) 1.1登录数据库 1.2数据库里创建glance 1.3授权对glance数据库的正确访问 1.4退出数据库 1.5创建glance用户密码为000000 1.6增加admin角色 1.7创建glance服务 1.8创建镜像服务API端点 2、安装gla…...
谈一谈你对View的认识和View的工作流程
都2023年了,不会还有人不知道什么是View吧,不会吧,不会吧。按我以往的面试经验来看,View被问到的概率不比Activity低多少哦,个人感觉View在Android中的重要性也和Activity不相上下,所以这篇文章将介绍下Vie…...
Redis集群的脑裂问题
集群脑裂导致数据丢失怎么办? 什么是脑裂? 先来理解集群的脑裂现象,这就好比一个人有两个大脑,那么到底受谁控制呢? 那么在 Redis 中,集群脑裂产生数据丢失的现象是怎样的呢? 在 Redis 主从架…...
互斥信号+任务临界创建+任务锁
普通信号量 1、信号量概念 2、创建信号量函数 3、互斥信号量 创建互斥信号量函数 等待信号量函数 释放互斥信号量 4、创建任务临界区 5、任务锁 任务上锁函数 编辑 任务结束函数 效果 普通信号量 1、信号量概念 信号量像是一种上锁机制,代码必须获…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
