网站建设设计制作公司,武夷山景区网站建设优点,公司logo在线设计生成器,在线视频链接生成器目录
1 Z(zombie)-僵尸进程
2 孤儿进程
3 环境变量
3.1 基本概念
3.2 测试HOME
3.3 和环境变量相关的命令
3.4 环境变量的组织方式
3.5 环境变量通常是具有全局属性的 在讲环境变量之前#xff0c;我们先把上次遗留知识点给总结了#xff08;僵尸进程和孤儿进程…目录
1 Z(zombie)-僵尸进程
2 孤儿进程
3 环境变量
3.1 基本概念
3.2 测试HOME
3.3 和环境变量相关的命令
3.4 环境变量的组织方式
3.5 环境变量通常是具有全局属性的 在讲环境变量之前我们先把上次遗留知识点给总结了僵尸进程和孤儿进程
1 Z(zombie)-僵尸进程 僵死状态Zombies是一个比较特殊的状态。当进程退出并且父进程使用wait()系统调用,后面讲 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 。僵死进程会以终止状态保持在进程表中并且会一直在等待父进程读取退出状态代码。 所以只要子进程退出父进程还在运行但父进程没有读取子进程状态子进程进入Z状态。我们来创建一个僵尸进程的栗子 1 #includeiostream2 #includeunistd.h3 #includestdio.h4 using namespace std;5 6 int main()7 {8 pid_t ret fork();9 if(ret0)10 {11 while(1)12 {13 //child14 printf(我是一个子进程pid:%d,ppid%d\n,getpid(),getppid());15 sleep(1); 16 return 1;17 }18 }19 else20 {21 while(1)22 {23 //parent24 printf(我是一个父进程pid:%d,ppid%d\n,getpid(),getppid());25 sleep(1);26 }27 }28 return 0;29 }当我们查看该进程时 不难发现子进程已经处于僵尸状态了那这样子进程不就没法回收了吗该进程就会一直占有CPU资源那不就造成了内存泄露了吗对的。另外僵尸进程是不能够用命令杀掉的因为已经退出。
我们总结下僵尸进程的危害 进程的退出状态必须被维持下去因为他要告诉关心它的进程父进程你交给我的任务我办的怎么样了。可父进程如果一直不读取那子进程就一直处于Z状态维护退出状态本身就是要用数据维护也属于进程基本信息所以保存在task_struct(PCB)中换句话说Z状态一直不退出PCB一直都要维护 那一个父进程创建了很多子进程就是不回收是不是就会造成内存资源的浪费。因为数据结构对象本身就要占用内存想想C中定义一个结构体变量对象是要在内存的某个位置进行开辟空间 最终会造成内存泄漏如何避免我们将放到后面来讲。 2 孤儿进程 父进程如果提前退出那么子进程后退出进入Z之后那该如何处理呢 父进程先退出子进程就称之为“孤儿进程” 孤儿进程被1号init进程领养。 上面我们提到了子进程先退出就是僵尸进程那么父进程先退出呢
我们想想此时父进程会是僵尸状态吗
答案是不会的父进程在此时会被他自己的父进程bash)回收而它的子进程则会交给1号进程领养我们可以修改一下代码让父进程先退出然后运行 这时子进程已经被1号进程给领养了我们想要杀掉该进程就可以用
killall 文件名
我们不难看出孤儿进程正常情况下是不会有内存泄漏的。 3 环境变量
3.1 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数如我们在编写C/C代码的时候在链接的时候从来不知道我们的所链接的动态静态库在哪里但是照样可以链接成功生成可执行程序原因就是有相关环境变量帮助编译器进行查找。 环境变量通常具有某些特殊用途还有在系统当中通常具有全局特性。相信大家在学习Java的时候都应该配置过环境变量这是大家学习Java的第一步相信大家在配置环境变量是心里非常疑惑为啥要配置环境变量呢接下来我会慢慢为大家解答的。
首先为问大家一个问题为啥我们Makefile生成了可执行文件后再运行要加上./
不加./就找不到该文件了吗答案是是的只有加上了./我们才能够正确定位到我们想要找的位置但是像我们使用的一些基本命令像whoami pwd 等等为啥就不用了呢
这就是我们今天要讲的主题因为配置了环境变量。
我们可以使用 env 来查看环境变量:
[grmVM-8-12-centos lesson7]$ env
XDG_SESSION_ID342794
HOSTNAMEVM-8-12-centos
SHELL/bin/bash
TERMxterm
HISTSIZE3000
SSH_CLIENT117.172.173.113 7924 22
OLDPWD/home/grm
SSH_TTY/dev/pts/0
USERgrm
LD_LIBRARY_PATH:/home/grm/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
LS_COLORSrs0:di01;34:ln01;36:mh00:pi40;33:so01;35:do01;35:bd40;33;01:cd40;33;01:or40;31;01:mi01;05;37;41:su37;41:sg30;43:ca30;41:tw30;42:ow34;42:st37;44:ex01;32:*.tar01;31:*.tgz01;31:*.arc01;31:*.arj01;31:*.taz01;31:*.lha01;31:*.lz401;31:*.lzh01;31:*.lzma01;31:*.tlz01;31:*.txz01;31:*.tzo01;31:*.t7z01;31:*.zip01;31:*.z01;31:*.Z01;31:*.dz01;31:*.gz01;31:*.lrz01;31:*.lz01;31:*.lzo01;31:*.xz01;31:*.bz201;31:*.bz01;31:*.tbz01;31:*.tbz201;31:*.tz01;31:*.deb01;31:*.rpm01;31:*.jar01;31:*.war01;31:*.ear01;31:*.sar01;31:*.rar01;31:*.alz01;31:*.ace01;31:*.zoo01;31:*.cpio01;31:*.7z01;31:*.rz01;31:*.cab01;31:*.jpg01;35:*.jpeg01;35:*.gif01;35:*.bmp01;35:*.pbm01;35:*.pgm01;35:*.ppm01;35:*.tga01;35:*.xbm01;35:*.xpm01;35:*.tif01;35:*.tiff01;35:*.png01;35:*.svg01;35:*.svgz01;35:*.mng01;35:*.pcx01;35:*.mov01;35:*.mpg01;35:*.mpeg01;35:*.m2v01;35:*.mkv01;35:*.webm01;35:*.ogm01;35:*.mp401;35:*.m4v01;35:*.mp4v01;35:*.vob01;35:*.qt01;35:*.nuv01;35:*.wmv01;35:*.asf01;35:*.rm01;35:*.rmvb01;35:*.flc01;35:*.avi01;35:*.fli01;35:*.flv01;35:*.gl01;35:*.dl01;35:*.xcf01;35:*.xwd01;35:*.yuv01;35:*.cgm01;35:*.emf01;35:*.axv01;35:*.anx01;35:*.ogv01;35:*.ogx01;35:*.aac01;36:*.au01;36:*.flac01;36:*.mid01;36:*.midi01;36:*.mka01;36:*.mp301;36:*.mpc01;36:*.ogg01;36:*.ra01;36:*.wav01;36:*.axa01;36:*.oga01;36:*.spx01;36:*.xspf01;36:
PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
MAIL/var/spool/mail/root
PWD/home/grm/lesson7
LANGen_US.utf8
HOME/home/grm
SHLVL2
LOGNAMEgrm
SSH_CONNECTION117.172.173.113 7924 10.0.8.12 22
LESSOPEN||/usr/bin/lesspipe.sh %s
PROMPT_COMMANDhistory -a; history -a; history -a; history -a; printf \033]0;%s%s:%s\007 ${USER} ${HOSTNAME%%.*} ${PWD/#$HOME/~}
XDG_RUNTIME_DIR/run/user/0
HISTTIMEFORMAT%F %T
_/usr/bin/env不难发现上面出现了很多配置了的环境变量像 PATH : 指定命令的搜索路径 HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录) SHELL : 当前Shell,它的值通常是/bin/bash 还有很多这里就不一一列举了大家可以在上面找到。
假设我们要查询pwd在哪个目录下可以用命令
[grmVM-8-12-centos lesson7]$ which pwd
/usr/bin/pwd我们查看一下环境变量的方法
echo $NAME
例如
[grmVM-8-12-centos lesson7]$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin我们很容易验证pwd的绝对路径
[grmVM-8-12-centos lesson7]$ ls /usr/bin/pwd
/usr/bin/pwd那我们是不是只要将我们可执行文件添加到环境变量中就可以不用加./了呢
我们可以来试试
添加环境变量的方法
export PATH$PATH:程序所在路径
这时我们直接运行hello程序依旧能够跑起来 假如我们不小心将命令写成了这个样子
export PATH程序所在路径
这时我们系统自带的环境变量将被我们新加入的环境变量所覆盖大家这时也不要担心我们将XShell关闭后重新打开就好了。
3.2 测试HOME
[grmVM-8-12-centos lesson7]$ cd ~
[grmVM-8-12-centos ~]$ pwd
/home/grm
[grmVM-8-12-centos ~]$ echo $HOME
/home/grm我们不难发现我们平常用的pwd指令本质上就是将其添加到了环境变量中。
3.3 和环境变量相关的命令 1. echo: 显示某个环境变量值 2. export: 设置一个新的环境变量 3. env: 显示所有环境变量 4. unset: 清除环境变量 5. set: 显示本地定义的shell变量和环境变量 我们看下面的命令
[grmVM-8-12-centos ~]$ val20
[grmVM-8-12-centos ~]$ echo val
val
[grmVM-8-12-centos ~]$ echo $val
20下面我们加入的val在环境变量中吗
我们通过env命令查询后发现没有在环境变量中这种叫做本地变量只在Shell内部有效。
要想导入环境变量得用export命令就像上面我们使用export导入环境变量一样。当我们使用set时就能够看见我们写入的本地变量和环境变量不过这个命令很少用。
3.4 环境变量的组织方式
大家心中的main函数应该是无参的因为我们平时写代码从来都不会些main函数的参数。但是实际上main函数1最多是有3个参数的分别是int argc, char *argv[], char *env[]
我们可以来看看命令行第3个参数究竟是什么
我们创建一个测试文件并向里面写入 1 #includeiostream2 using namespace std;3
E 4 int main(int argc,char* argv[],char* env[])5 {6 for(int i0;env[i];i)7 {8 coutenv[i]endl; 9 }10 return 0;11 }运行后发现 这不就是我们刚才通过env查到的环境变量吗对的其实main函数中第三个参数是一个指针数组指向的就是环境变量表。
我们也可以通过第三方变量environ获取:
#include iostream
using namespace std;
int main(int argc, char *argv[])
{extern char **environ;int i 0;for(; environ[i]; i){printf(%s\n, environ[i]);}return 0;
}
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。
我们还可以通过系统调用获取或设置环境变量。这样做的好处是每次寻找环境变量不用每次都遍历环境变量表。
#include iostream
#include cstdlib.h
int main()
{printf(%s\n, getenv(PATH));return 0;
}
常用getenv和putenv函数来访问特定的环境变量。
putenv我们放到后面来讲解。
那么char* argv[]又是什么鬼呢
我们来看一段代码 1 #includeiostream2 using namespace std;3 4 int main(int argc, char* argv[],char* env[])5 { 6 for(int i0;iargc;i)7 {8 coutargv[i]endl;9 }10 }当我们这样运行时 不难发现argv[]将我们在命令行上敲出来的选项都打印出来了这也是我们输入一些命令时(例如ls )附带一些选项时的原理为什么当执行不同的选项时结果会是不同的就是因为当执行不同的选项时将选项的结果都保存到了argv[]中当执行时就会拿出保存的结果来执行具体的执行方式我们将放到后面来讲。
3.5 环境变量通常是具有全局属性的
环境变量通常具有全局属性可以被子进程继承下去.
#include stdio.h
#include stdlib.h
int main()
{char * env getenv(MYENV);if(env){printf(%s\n, env);}return 0;
}
直接查看发现没有结果说明该环境变量根本不存在:当我们导出环境变量export MYENVhello world 再次运行程序发现结果有了说明环境变量是可以被子进程继承下去的这张表是由bash制作而成的 总结 环境变量本质就是内存级的一张表这张表在用户登录系统的时候进行给特定的用户形成属于自己的环境变量表。环境变量中的每一个都有自己的应用场景有的是按路径查找的有的是进行身份验证的有的是进行动态库查找的有的是用来确定当前路径等等。环境变量的相关数据是从相关的配置文件中读到的每一个元素都是kv的。