Linux下监视进程运行状况(一)

2006-08-05 07:26:57

-----------------------
下面是发在论坛上面的原文。
转来这里的时间是8月5日。因为论坛上根本没人看:(
我没学过latex,文章的格式仅仅是传统ubb的格式。
我想文章标题以后可能需要改动,因为文章的内容以后不但会涉及程序运行时资源的监视,也会包括控制部分。
希望看客喜欢。
-----------------------

[说在前面]

我想这个主题对很多初涉Linux开发的人都有帮助。

我本身也是刚接触Linux下开发的新手,说的不对,请大家指正。

以连载的形式分3次左右写完,想到哪写哪,都是经验总结。因为时间有限,一次的内容不会很多。

我发现找不到合适的板块来发这个主题,本文章的分类应该是“开发 -> Unix系统编程”。

本文作者:Fluke at Ospattern(dot)net

作者背景:在校计算机本科生,Linux使用者,C程序开发者,研究都不深。

本章属性:可以分发,没有版权,文中引用代码,也许有部分和某些程序相同,但我不认为是侵权,因为代码本来就有固定的模式,也许是我学习之后,忘了故意去修改什么。如果侵犯了您的权力,请与我联系,并诚挚请您原谅。

[正文]

Linux下监视一个程序的运行状况,有不同的方法,适用范围也不大一样。我知道的一些方法如下:

1. Process accounting

  这个是新内核(kernel 2.x.x都支持)支持的一个功能,不过在编译的时候,需要Enable它,默认是没有打开的。打开之后,可以通过几个命令来获取正在运行的程序的CPU Time, Memory占用等等信息。

  优点,信息全面,操作也容易。缺点,需要重新编译内核,很多用户不希望这样,尤其是现在很多使用标准化的发行版的用户都不希望去改变系统的默认设定。

2. Top, ps, cat /proc/pid/...

  我们还可以通过top, ps命令来或者直接cat /proc/pid(这里pid是系统分配给程序的一个id,运行时会在/proc目录下有相应的资源文件,不是本文的重点,本人对此也十分不熟悉,仅仅是知道)目录下面的文件查看系统正在运行的程序,和实时的系统资源占用。

  优点,方便,缺点,对于需要跟踪某进程的运行情况的用户,这种方法就不适用了。

3. 通过在子进程来运行需要监视的程序,通过标准的GNU C函数库来获取子进程资源

  这种是本文要讲述的方法。优点显而易见,能从头到尾跟踪程序的运行,不但能获取其资源状况,还能控制其运行,比如在程序试图获取更多系统资源(CPU时间或者内存等)时发送信号使其结束。

  那么,我们从什么地方开始呢?

  gnu time。一个很小巧的计算程序运行时间的程序,也许很多人都用过。我们创建一个小程序(当然你也可以不使用自己创建的程序,直接统计一下你系统上已经有的程序,比如find),然后用gnu time来统计一下。以后在计算其他资源的时候,我们还会修改这个程序,使其占用一定的内存或者什么的,以达到我们的测试要求。OK,我们来创建一个c++程序(我只会这个),叫做AccountMe.cpp。

下面是AccountMe.cpp的内容:[ DISCUZ_CODE_34 ]然后,用g++来编译程序,我这里gcc的版本是4。命令如下:[ DISCUZ_CODE_35 ]  好了,看看这个程序会占用多少时间,输入如下命令:[ DISCUZ_CODE_36 ]  然后你会看到,类似下面的统计:[ DISCUZ_CODE_37 ]  上面程序运行的原理是,time接受第一个参数argv[1]得到要运行的进程的路径,然后fork()出一个子进程,子进程要做的事情是通过execvp()系列函数运行程序argv[1],父进程要做的事情有几件:1. 得到开始时间start_time。2.在waitpid()系列函数,等待子进程,直到结束,或者直到自己设置的限制以后,终止子进程。3.得到结束时间end_time。最后计算花费时间run_time = end_time - start_time。

  很简单的过程,不是么?

  在本篇的最后,我仅仅想和大家分享一下怎么在C里面创建子进程,怎么样运行外部进程。其他的,留待本系列的后续文章。至于C语言里面资源的统计,读者可以参开fork,wait,limit等manpage,以及google上查找详细资料,本文不打算充当这方面的知识普及者(本人并没有研究透彻,不好扩展下去),要用到的东西,会在用的时候简单介绍,或者直接用例子说话。

  这里来看看一段运行子进程的代码,代码本身只充当运行者的身份,出了获取被运行者的返回值之外,什么也不做。

ProcRunner.cpp的内容:[ DISCUZ_CODE_38 ]  编译上面的程序,用来运行刚才我们创建的AccountMe,然后我们来看看程序运行出错和正常退出的情况。下面是编译的命令:[ DISCUZ_CODE_39 ]  运行AccountMe:[ DISCUZ_CODE_40 ]  这里要用绝对路径,因为我们的程序里面没有添加处理路径的功能(这个留待以后讨论,在这里并不重要)。

  因为程序正常退出,所以我们看到的情况如下:[ DISCUZ_CODE_41 ]  现在我们给AccountMe一些错误,看看ProcRunner有什么反应。当然,你也可以用signal去结束掉AccountMe来玩玩;)

  我简单的使AccountMe返回-1,然后运行ProcRunner。发现返回值变了:[ DISCUZ_CODE_42 ]  发现,ProcRunner捕获的错误号码是255而不是-1,这是因为错误号码不是简单的是错误程序的返回值,不过包含了返回值在其二进制位中,这次不讨论。

  好了,这部分已经结束,我花了一个多小时来写,写完之后搜索了一下网上的文章,发现我的文章也许没有必要存在,不过没有关系,有人喜欢的话,我会继续往下写:)
------------
Tue 01 Aug 2006 04:19:42 AM CST fluke on Archlinux

TAG:

删除 guest 发布于2006-08-26 08:03:15
bu cuo!!!!!111
joejoe0332 删除 joejoe0332 发布于2006-08-08 02:21:27
欢迎来博客~
我来说两句

-5 -3 -1 - +1 +3 +5

Open Toolbar