希望你开心,希望你健康,希望你幸福,希望你点赞!
最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!!
喵喵喵,你对我真的很重要!
一个小插曲~
严肃的问题,猫猫和花花可以兼得吗?
答案是不可以,猫猫吃了花花,会嘎掉!
僵尸进程
僵尸进程是操作系统中一个常见的概念,具体指已经终止但仍然占用系统资源的进程。僵尸进程的形成主要是由于父进程在子进程终止后没有正确处理子进程的退出状态。以下是对僵尸进程的详细解析:
定义与特征
-
定义
- 僵尸进程是指子进程已经结束运行,但父进程还未对其进行善后处理(如调用wait()或waitpid()函数)的状态。此时,子进程的进程描述符(PCB)仍然保留在系统中,占用一定的内存空间。
-
特征
- 僵尸进程不再消耗CPU资源,但它们的进程描述符(PCB)仍然存在于系统中,这意味着它们会占用一定的内存资源。如果系统中存在大量的僵尸进程,可能会导致系统资源的浪费和性能下降。
产生原因
僵尸进程的产生通常是因为父进程没有调用wait()或waitpid()等函数来清理子进程的状态。当子进程结束时,它会发送一个SIGCHLD信号给父进程,通知父进程它已经结束。如果父进程没有处理这个信号或者没有调用wait()系列函数来清理子进程的状态,子进程就会变成僵尸进程。
解决方法
为了解决僵尸进程问题,可以采取以下几种方法:
- 使用wait()或waitpid()系统调用:父进程可以通过调用wait()或waitpid()函数来获取子进程的退出状态,并清理子进程所占用的资源。
- 忽略SIGCHLD信号:父进程可以使用signal()函数将SIGCHLD信号的处理函数设置为SIG_IGN,表示忽略该信号。这样,在子进程终止后,内核会自动回收子进程的资源,不会产生僵尸进程。
- 使用双向管道进行进程间通信:父进程可以创建一个双向管道,子进程在终止时通过管道发送一个消息给父进程。父进程在接收到消息后调用wait()或waitpid()来处理子进程的终止状态。
- 监控和清理僵尸进程:可以使用系统命令(如ps、grep等)来查找僵尸进程,并通过杀死其父进程来间接清理僵尸进程。但请注意,直接杀死僵尸进程是不可能的,因为它们已经处于死亡状态。
注意事项
- 僵尸进程本身不能被直接杀死,因为它们已经死亡,但是它们的状态信息仍然保留在系统中。
- 如果系统中出现大量僵尸进程,可能需要检查系统上的程序是否存在问题,或者是否存在某些服务或进程管理不当的情况。
- 频繁地出现僵尸进程可能表明系统或应用程序中存在问题,需要进一步的调查和修复。
孤儿进程
孤儿进程是操作系统中的一个概念,具体指的是在其父进程执行完成或被终止后仍继续运行的一类进程。这些孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
产生原因
在类UNIX操作系统中,子进程是通过父进程创建的,子进程再创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程到底什么时候结束。当一个父进程由于正常完成工作而退出或由于其他情况被终止,而它的一个或多个子进程却还在运行,那么这些仍在运行的子进程就会成为孤儿进程。
处理机制
为避免孤儿进程退出时无法释放所占用的资源而僵死,进程号为1的init进程会接受这些孤儿进程,这一过程也被称为“收养”(英语:re-parenting)。init进程会循环地调用wait()函数来等待其已经退出的子进程,包括这些被收养的孤儿进程。当孤儿进程结束时,init进程会负责清理它们的状态和资源,确保系统资源的有效回收。
特点与影响
- 无父进程:孤儿进程是没有父进程的进程,它们的父进程ID会被设置为1,即init进程的ID。
- 资源回收:由于init进程的存在,孤儿进程在结束时能够确保其占用的资源得到回收,因此孤儿进程本身并不会对系统造成危害。
- 常见现象:在Unix/Linux系统中,孤儿进程是正常现象,系统能够自动处理它们的状态和资源回收问题。
环境变量
Linux环境变量是操作系统中用来指定操作系统运行环境的一些参数,是操作系统为了满足不同的应用场景预先在系统内设置的一大批全局变量。以下是关于Linux环境变量的详细解析:
一、环境变量的分类
Linux环境变量可以按照不同的标准进行分类,主要包括以下几种:
- 按照生命周期分类:
- 临时环境变量:用户利用export命令在当前终端下声明环境变量,关闭Shell终端后失效。
- 永久环境变量:在环境变量脚本文件中配置,用户每次登录时会自动执行这些脚本,相当于永久生效。
- 按照作用域分类:
- 系统环境变量:对所有用户和进程都可见,通常在系统启动时被设置,并被所有用户和进程共享。
- 用户环境变量:每个用户独立设置,只对该用户及其相关进程可见。这些变量可以在登录时通过不同的配置文件(如.bashrc、.bash_profile、.profile等)设置。
- 进程环境变量:由特定进程设置,并且仅对该进程及其子进程可见。
二、常见的环境变量
Linux系统中有很多常用的环境变量,它们各自承担着不同的作用,以下是一些常见的环境变量:
- PATH:决定了shell将到哪些目录中寻找命令或程序。它是一系列由冒号分隔的目录,当输入一个命令时,shell会按照PATH中定义的顺序去这些目录中查找可执行文件。
- HOME:当前用户主目录的路径。
- USER:当前用户的用户名。
- SHELL:当前用户默认使用的shell类型。
- LANG:指定系统的默认语言。
- LD_LIBRARY_PATH:指定系统在哪些目录中查找共享库文件。
- TERM:指定当前终端的类型。
- PS1:定义命令行提示符的格式。
三、查看环境变量
在Linux中,可以使用多种方法来查看环境变量:
- echo命令:例如,
echo $PATH
可以查看PATH环境变量的值。 - printenv命令:列出所有环境变量及其对应的值。
- env命令:与printenv类似,也是用于显示所有环境变量。
- set命令:显示当前shell的本地定义的环境变量和局部变量。
四、添加和删除环境变量
添加环境变量
- 临时添加:
- 使用export命令在当前终端下声明环境变量,例如
export PATH=$PATH:/new/path
。这种方法只对当前终端有效,关闭终端后失效。
- 使用export命令在当前终端下声明环境变量,例如
- 永久添加:
- 编辑用户的个人配置文件(如.bashrc、.bash_profile、.profile等),在其中添加export命令,然后保存并退出。之后,可以通过执行
source ~/.bashrc
(或相应的配置文件)来使更改立即生效,或者在下次登录时自动生效。
- 编辑用户的个人配置文件(如.bashrc、.bash_profile、.profile等),在其中添加export命令,然后保存并退出。之后,可以通过执行
删除环境变量
- 临时删除:
- 使用unset命令,例如
unset PATH
(这会删除整个PATH环境变量,通常不推荐这样做),或者更精细地删除PATH中的某个特定路径(这需要使用一些字符串处理技巧)。
- 使用unset命令,例如
- 永久删除:
- 编辑相应的配置文件,删除或注释掉相应的export命令,然后保存并退出。之后,通过执行
source
命令或重新登录来使更改生效。
- 编辑相应的配置文件,删除或注释掉相应的export命令,然后保存并退出。之后,通过执行
五、环境变量的作用
环境变量在系统当中通常具有全局属性,可以被子进程继承。它们对于系统的正常运行和程序的执行起着至关重要的作用。通过合理设置环境变量,可以方便地控制程序的运行环境,提高系统的灵活性和可配置性。
六、环境变量的加载顺序
在Linux系统中,环境变量的加载顺序通常遵循以下规则(可能因发行版而异):
- /etc/environment(如果存在):这是系统级的环境变量配置文件,对所有用户都有效。
- /etc/profile:这是系统级的全局配置文件,对所有用户都有效。它会调用其他配置文件,如/etc/bash.bashrc等。
- ~/.bash_profile、~/.bash_login、~/.profile(按此顺序查找):这些是用户级的配置文件,用于设置用户个性化的环境变量。bash shell会按照顺序查找这些文件,并执行找到的第一个文件。
- ~/.bashrc:这是bash shell特有的配置文件,用于设置bash shell的特定配置和环境变量。每次打开新的bash shell时,该文件都会被执行。
code:code.c
gcc -o $@ $^ -std=c99
.PHONY:clean
clean:
rm -f code
#include <stdio.h>
#include <unistd.h>
#include <string.h>
// code -opt1/-opt2/-opt3
int main(int argc, char *argv[], char *env[])
{
printf("我是一个进程,我的pid: %d\n", getpid());
for(int i=0; env[i]; i++)
{
printf("env[%d]: %s\n", i, env[i]);
}
if(argc != 2)
{
printf("Usage: code opt\n");
return 1;
}
if(strcmp(argv[1], "-opt1") == 0)
{
printf("功能1\n");
}
else if(strcmp(argv[1], "-opt2") == 0)
{
printf("功能2\n");
}
else if(strcmp(argv[1], "-opt3") == 0)
{
printf("功能3\n");
}
else
{
printf("默认功能\n");
}
return 0;
}
希望你开心,希望你健康,希望你幸福,希望你点赞!
最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!!
喵喵喵,你对我真的很重要!