Linux进程操作(进程环境--程序的启动和退出)

程序的启动和退出

在shell中启动一个程序

Linux shell 本身可以运行两种文件:二进制可执行文件解释器文件(例如shell脚本);
启动一个程序的方法:

$ 程序的路径名 命令行参数 //例如: ./hello

参数说明:

  • 程序的路径问题:shell 本身有一个环境变量PATH,其中包含有shell所要搜寻的路径。如果指定了一个程序路径名,shell 可以直接到指定的路径搜索用户要执行的文件。如果指定的路径上找不到该文件或者根本没有指定路径,shell 会在这些指定路径中搜索所要执行的程序的文件名,例如上例就是要在指定路径名中搜索文件名为hello的文件。如果在PATH所包含的这些路径中仍然找不到需要的文件,shell 会执行命令失败。反之如果找到该文件,shell 则会使用加载程序将该程序文件由外存加载到内存中运行。

  • shell命令本质:由此可知,所谓的shell 命令其实也是一些二进制可执行文件,它们并不是shell程序的一部分,而是存储在文件系统中的某处。

  • 对于一般的Linux系统,Linux 命令的执行文件存储在 “/bin” 目录下,如果不是,可以查询shell中的PATH环境变量。将上面提到的hello程序复制到该目录下。

  • PATH:简单说PATH就是一组路径的字符串变量,当你输入的命令不带任何路径时,LINUX会在PATH记录的路径中查找该命令。有的话则执行,不存在则提示命令找不到。比如在根目录/下可以输入命令ls,在/usr目录下也可以输入ls,但其实ls命令根本不在这个两个目录下,当你输入ls命令时LINUX会去/bin,/usr/bin,/sbin等目录寻找该命令。而PATH就是定义/bin:/sbin:/usr/bin等这些路劲的变量,其中冒号为目录间的分割符。由此可知,在Linux环境下,用户可以使用自己编制的命令。不过为了和系统带有的Linux基本命令区别,用户自己的命令往往集中于“/usr/bin" 目录下,该目录也包含在PATH环境变量之中。用户也可以将自已制作的命令集中到-一个自已设定的目录中,不过要将该目录的路径添加到PATH环境变量中才可以。

  • 查看PATH: echo $PATH

  • 修改PATH:
    (1)命令行中修改: ** PATH=$PATH:/usr/local/apache/bin** 使用这种方法,只对当前会话有效,也就是说每当登出或注销系统以后,PATH设置就会失效。
    (2)在profile中设置PATH:** vi /etc/profile** 找到export行,在下面新增加一行,内容为:export PATH=¥PATH:/usr/local/apache/bin 注:= 等号两边不能有任何空格。这种方法最好,除非手动强制修改PATH的值,否则将不会被改变。编辑/etc/profile后PATH的修改不会立马生效,如果需要立即生效的话,可以执行** source profile命令。
    (3)在当前用户的profile中设置PATH:
    vi ~/.bash_profile** 修改PATH行,把/usr/local/apache/bin添加进去,如:PATH=¥PATH:HOME/bin:/usr/local/apache/bin , ** source ~/.bash_profile** 让这次的修改生效。注:这种方法只对当前用户起作用的,其他用户该修改无效。

加载一个程序

  • 程序格式:
  • 内部结构:
  • 程序头:
  • 程序加载的简单过程:
    (1)从目标文件中读取足够的头部信息,找出需要多少地址空间;
    (2)分配地址空间,如果目标代码的格式具有独立的段,那么就将地址空间按独立的段划分;
    (3)将程序读入地址空间的段中;
    (4)将程序末尾的bss段空间填充为0,如果虚拟内存系统不自动这么做时;
    (5)如果体系结构需要,创建一个堆栈段( stack segment);
    (6)设置诸如程序参数和环境变量的其他运行时信息;
    (7)开始运行程序,从main函数的地址初开始顺序执行程序。

加载地址

了解了加载的过程后,由此可以得出一个对应用级程序员最有用的结论:就是由于加载器每次将程序加载前需要分配地址空间,所以每次程序加载时不会使用同样的地址。

  • 参考书籍:《连接器和加载器》

退出程序

概述:在Linux环境下,一个进程有3种退出方式:进程自愿退出、进程收到一个信号退出,以及进程执行一个导致异常的操作后退出。

  • 自愿退出:自愿退出是一般的进程退出形式,在C语言源代码中体现为return语句和exit函数调用。在进程退出时,需要回收进程所分配的资源,例如,进程的地址空间,文件描述符等。在回收资源的同时,操作系统也对每一项资源进行 善后处理,例如对于打开的文件,在释放文件描述符的同时,还要将缓冲区中的内容“冲洗”到外存上,保证文件缓冲区的内容和外存中的内容一致。一个进程所得到的资源分为两部分,一部分资源在进程结束运行的时候就会释放。另一部分资源则由系统保存,用于以后对进程的统计。前者往往供进程本身使用,后者往往提供给进程的父进程,因此,用于进程统计的资源是否释放则取决于进程的父进程。如果父进程不释放进程的统计资源,就会导致僵F进程的出现,由此可见在进程正常退出后,除了操作系统所做的资源释放外,父进程释放掉进程的统计资源也是相当重要的。
  • 收到一个信号退出: 进程退出的第2种情况是接收到一个信号后退出。这种情况很常见,往往出现在父进程对子进程的操作上。例如,在shell 中运行一个程序,如果不想让其执行,则可以使用Ctrlt+c组合键结束此进程的执行。这一操作实际上由shell (父进程)向运行的程序(子进程)发出了一个终止程序运行的信号。子进程在接收到信号后,也会像自愿退出时一样,处理分配的资源,并且正常退出。
  • 执行一个异常操作: 以上2种退出方法都是在程序预期之下退出的,第3种情况则是在程序没有准备的情况下退出的。这时候操作系统也会对其资源进行回收,但是有可能不会对这些资源作善后处理。这样的退出方式称为异常退出。后面会继续讲到异常退出是一 种特殊的信号退出,因为在这种情况下,发出信号的不是某一个进程而是操作系统本身。

进程终止处理函数

Linux环境下允许在进程退出的时候调用一些用户自己定义的函数,这些函数成为终止处理函数。Linux 规定最多可以设置32个这样的进程终止处理函数。Linux 环境下使用atexit函数登记函数)设置进程终止处理函数,其函数原型为:

#include<stdlib.h>
int atexit(void(*func)(void));

参数说明:

  • 参数是一个函数指针,该函数指针指向一个返回值和参数都是void型的函数,也就是说,进程终止处理函数不接受任何参数。因为这些终止函数是在进程结束时调用的,因此也不返回任何值。
  • 如果成功设置了进程终止处理函数,atexit 函数返回0,失败则返回非零值。因此在检查atexit函数的返回值时,不应检查atexit 的返回值是否等于-1,而是!= 0.
  • 进程终止处理函数的调用顺序与设置时相反!!
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值