标签 Kernel 下的文章

玩转top

相信很多人和我一样,top是自己日常使用最多的linux资源查看工具。不过仅限于一些简单的日常场景罢了:敲入top命令,看看哪些进程占用 CPU较多,然后对这些CPU占用较多的进程逐一处理一下。显然这样使用top有些大才小用了。

以前在监控工具使用方面总是浅尝辙止,并未做过多深入研究。近来愈来愈觉得有必要针对几种常用工具好好学习一下了。而top便首当其冲。top是一款 以查看进程(task)信息为中心的Linux系统性能监控工具,通过top我们可以查看到进程相关的cpu和内存占用相关的实时采样信息,因此 top尤其适合用于持续跟踪分析某些进程对系统cpu和内存的占用情况以及对系统负荷的影响。

入门

top的入门使用极其简单,就像前面所说的简单地的输入"top",我们就能看到top的输出了。

top – 06:35:47 up 7 min,  3 users,  load average: 1.00, 1.18, 0.67
Tasks: 189 total,   2 running, 186 sleeping,   0 stopped,   1 zombie
Cpu(s): 30.5%us,  7.6%sy,  0.0%ni, 60.5%id,  1.5%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1534164k total,  1423392k used,   110772k free,    67328k buffers
Swap:   999420k total,      144k used,   999276k free,   576924k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                      
 1954 tonybai   20   0  316m  55m  26m S   26  3.7   0:36.53 compiz                                       
 2308 tonybai   20   0  499m  84m  39m S   13  5.6   1:07.63 chrome
… …

top的输出大致分为上下两个部分,上半部分输出到是系统的总体负荷信息,下半部分则是分进程列出进程的各种属性信息。

总体负荷信息由五行组成:

第一行:top – 06:35:47 up 7 min,  3 users,  load average: 1.00, 1.18, 0.67。
这行的输出与uptime命令是一样一样的,不信你可以单独执行一下uptime命令。我怀疑top就是直接调用uptime或使用uptime部分代码 得到的,毕竟它们都是procps(procps is the package that has a bunch of small useful utilities that give information about processes using the /proc filesystem.)工具集合的一员。这行输出了当前时间( 06:35:47)、自系统启动以来的累计时间(7 min),当前系统用户数(3 users),1分钟,5分钟以及15分钟的平均负荷( load average: 1.00, 1.18, 0.67)。

第二行:Tasks: 189 total,   2 running, 186 sleeping,   0 stopped,   1 zombie。
系统的进程信息汇总,包括总数以及处于各种状态的进程数量。

第三行:Cpu(s): 30.5%us,  7.6%sy,  0.0%ni, 60.5%id,  1.5%wa,  0.0%hi,  0.0%si,  0.0%st。
系统的CPU信息汇总,包括us(CPU用于运行用户空间进程的时间所占比例,不包括renice的用户进程)、sy(CPU用于运行内核进程的时间所占 比例)、ni(CPU用于运行用户空间被renice的进程的时间所占比例)、id(CPU空闲时间所占比例)、wa(CPU等待I/O完成时间所占用的 比例)、hi(处理硬件中断时间所占比例)、si(处理软中断时间所占比例)、st(虚拟机管理程序为其他task而从本虚拟机'偷取'的CPU时间所占 比例)。

第四行和第五行:
Mem:   1534164k total,  1423392k used,   110772k free,    67328k buffers
Swap:   999420k total,      144k used,   999276k free,   576924k cached

系统的内存以及交换区信息汇总,包括内存总量(mem total)、已使用内存(mem used)、空闲内存(mem free)以及交换区总量(swap total)、交换区使用量(swap used)、交换区空闲(swap free)。这里还有两个值buffers和cache,它们是内核使用的内存缓存,均是用于减少磁盘读取,提升系统性能的。buffers代表有多少内 存用于缓存磁盘数据块,目的是减少写磁盘次数;cache用于缓存从磁盘文件读取的数据,以减少读磁盘次数。

下半部分是进程属性信息展示区。默认情况输出的进程属性包括:
    PID(进程ID)
    USER(进程所有者的用户名)
    PR(进程的动态优先级)
    NI(Nice值,进程的base priority)
    VIRT (进程的虚拟内存用量,包括进程的二进制映像大小、数据区以及所有加载的共享库占用的size, = SWAP + RES)
    RES(进程使用的、未被换出的物理内存大小,= CODE + DATA)
    SHR(共享内存区域大小)
    S(进程状态)
    %CPU(上次刷新到现在运行该task的CPU时间所占百分比)
    %MEM(当前task所占用的内存百分比)
    TIME+  (自task启动后所使用的CPU时间累计)
    COMMAND (task对应的二进制程序名)

定制输出

top提供了强大的输出定制功能,无论是上半部分的系统整体负荷信息还是下半部分的进程属性信息展示都是可以根据使用的需求定制的。

整体负荷信息展示区的定制:
- 第一行展示/隐藏:通过点击键盘上的'l'键可以展示或隐藏第一行信息输出
- Task和CPU信息展示/隐藏:通过点击键盘上的't'键可以展示或隐藏Task和CPU行输出
- Mem和Swap信息展示/隐藏:通过点击键盘上的'm'键可以展示或隐藏Mem和Swap行输出

进程属性信息的显示定制:
默认情况下,我们可以看到top会显示进程的若干属性,包括PID、USER、PR、NI 、VIRT 、RES 、SHR、S、%CPU以及%MEM等。不过这些也仅仅是默认的而已,如果你不关住其中一些属性或关注其他一些属性,你完全可以自定义输出显示的进程属 性。点击键盘上的'f'键,top将为我们打开field选择页面:

Current Fields:  AEHIOQTWKNMbcdfgjplrsuvyzX  for window 1:Def
Toggle fields via field letter, type any other key to return

* A: PID        = Process Id                           0×00002000  PF_FREE_PAGES (2.5)
* E: USER       = User Name                            0×00008000  debug flag (2.5)
* H: PR         = Priority                             0×00024000  special threads (2.5)
… …

页面左侧列出了可选的所有进程属性。其中前面有*前缀的是当前已经选择的属性,比如PID。不过你可以通过点击PID对应的开关键'A'来取消对PID的 选择;同样你也可以点击未选择属性前面的开关键来选择对应的属性,比如敲击'p'来选择SWAP属性。定制完毕后回车回到top主页面,你就会看到你定制 后的结果了。

保存你的定制

如果你不想每次都在top启动后重新做定制操作,那就将你的定制保存到top的用户配置文件中。在定制后的top主页面上输入:'W',top会提示你:Wrote configuration to '/home/tonybai/.toprc,也就是说top会将你的定制保存在你的~/.toprc中。重启top看看,是否依旧是上次你定制后的结果呢^_^。

多视图

默认情况下top为我们打开了一个视图。不过top可不止支持一个视图。敲入'A'看看会发生什么?没错,你会看到上下分割的四副视图,另外在整个窗口的 左上角会出现反白的'1:Def',这是一个active视图的提示文字。反复输入'w',top会在各个视图间切换,左上角会在'1:Def'、 '2:Job'、'3:Mem'和'4:Usr'之间切换。‘1:Def'是默认视图,以CPU占用高低对task进行排序;'2:Job'这个视图看起 来比较陌生,里面展示的task多是些系统服务或内核线程;'3:Mem'视图则是以Mem占用高低对task进行排序;'4:Usr'视图则是按用户名 展示task。用'w'切换到某个视图后,可以输入'A'将该active视图放大为单视图铺满窗口。在多视图展示的情况下,还可以输入'-'来隐藏/展 示某种视图。另外这种多视图的配置也是可以保存在.toprc中的。

批处理模式

平时我们更多用的是在交互模式下运行的top,但交互模式下的数据无法记录下来,不便于事后分析,不过top的批处理模式可弥补这一不足。

执行top -b,即可让top以批处理模式运行。默认情况下top会不断重复执行,似乎批处理模式意义不大。不过我们可以限定批处理模式的运行间隔和运行次数,默认情况下top运行/更新间隔为3s,运行次数为无限制。我们可以通过一些命令行参数来设定这两个值,比如:

$> top -b  -d 1 -n 10

-d 用来设置更新间隔为1s;而-n 则设置批处理运行10次。

默认情况下top输出的task太多,我们可以通过指定相关进程或指定user来将关注面缩小,比如:

$> top -b -p 2500 -p 2501 -d 1 -n 10

这个命令只是会输出2500和2501这两个进程的相关信息。

$> top -b -u www-data -d 1 -n 10

这个命令只会输出www-data这个用户下的所有进程相关信息。

即便在批处理模式下,top依旧会输出整体负荷信息。这样一来对后续的数据后处理会带来些麻烦。一个好的方法是先定制top,再做批处理执行。比如先用 l,m,t把top的整体负荷信息都关闭掉,再定制好要关注的进程属性,保存到toprc中;之后再批处理运行top(可将输出结果重定向到某个数据文件 中),我们得到的数据就会比较规整,处理起来也十分方便了。

如何加入Linux内核开发社区(7)

本文翻译自The Linux Foundation的《How to Participate in the Linux Community》(基于2012-03-21最新版本),原作者为Jonathan Corbet(corbet@lwn.net)。 下面是该文章第七章、第八章以及第九章节的中译文。

 
7、高级主题
 
但愿此时此刻,你已经理解了内核开发过程是如何进行的。但仍然还有很多东西要学习!这一节将涵盖几个主题,这些主题对于那些致力于成为Linux 内核开发过程中固定一员的开发者来说是很有帮助的。
 
7.1、使用Git管理补丁
 
早在2002年,内核就开始使用分布式版本管理工具了,当时Linus首先使用的是一款名为BitKeeper的专有(proprietary) 应用。虽然BitKeeper是有争议的,但它所代表的软件版本管理方法几乎是没有任何争议的。分布式版本控制使得内核开发项目的开发效率获得了加速地提升。如今,有很多种可以替代BitKeeper的工具。不管结果如何,内核项目已经决定了将git作为其版本管理工具的选择。
 
使用git管理补丁可以使开发者的工作更加轻松,特别是当补丁的数量越来越多的情况下。Git也有其不完善的地方并且可能产生某种危险;它是一个年轻而强大的工具,目前其开发者仍然在对其进行改进。本文不会尝试教授读者们如何使用git;其自带的长文档提供了足够的资料。相反,这里着重关注git是如何融入到内核开发过程中去的。那些期望快速学会使用git的开发者可以在下面网址中找到更多信息:
 
http://git-scm.com/
 
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
 
并且可以在互联网上找到各种不同的教程。
 
第一件事就是阅读上述站点所提供的内容,在尝试使用git制作补丁之前充分理解git的工作原理。一个使用git的开发者应该能够从内核主线库获得代码拷贝、查看修改历史记录、向代码树提交改变以及使用分支等。对git重写历史的工具(例如rebase)的理解也是很有用的。Git尤其自己的术语与概念;一个git的新用户应该知道引用(refs)、远程分支(remote branches)、暂存区(index,译注:现在更多称之为stage)、快进合并(fast-forward merge)、推(push)和拉(pull)以及detached heads等。一开始这些可能会让人感到有些望而生畏,但通过一点点学习这些概念掌握起来也不是那么难。
 
使用git生成通过email提交的补丁是一种用来加快git学习速度的非常好的练习。
 
如果你准备创建一个供其他人查看的git源码树,你自然会需要一个服务器,其他人可以从该服务器上拉(pull)代码。如果你拥有一个可以访问互联网的系统,使用git-daemon搭建这个服务器将会相对简单一些。否则,一些出现在互联网上的免费的公共托管站点(例如,Github)可供使用。已被社区认可的开发者可以从kernel.org获得一个帐户,但这些可是来之不易的;更多内容请参见http://kernel.org/faq/ 。
 
正常的git工作流程涉及到许多分支使用。每行代码都可能被分离到一个独立的"主题分支"中并且独立维护。在Git中使用分支的代价非常小,我们没有理由不自由使用它们。并且,无论如何你都不应该在一个你想要其他人从中拉取(pull)代码的分支上进行开发。对公众开放的分支应该谨慎创建;只有当开发分支上的代码完成并具备发布条件时再将代码合并到补丁中,不要在完成之前就合并。
 
Git提供了一些功能强大的工具,它们可以让你重写开发历史。一个令人为难的补丁(可能是破坏了bisection的补丁,又或是有其他明显bug的补丁)可能在适当地方被修复或整体从开发历史中消失。一个补丁序列可以被重写,重写后就好似今天主线上最新的修改似的,即便你已经在这个补丁序列上工作几个月了。改变可以透明地从一个分支转移到另一个分支,等等。明智地的使用git所提供的能力对代码库历史进行修订可以有助于创建出问题更少的整洁的补丁集合。
 
然而,除了着迷于创建一个完美的项目历史之外,过度地使用git提供的能力可能会导致其他问题。重写历史将重写历史所对应的改变,将一个测试过(希望是)的内核树转化为一个未测试过的内核。但是,除此之外,如果没有有关项目历史的共享视图,开发者间的合作将不会那么容易;如果你重写了一段代码历史,并且其他开发者已经将这段代码拉入其个人代码库,你会让这些开发者的工作变得更为困难。因此,这里可以应用一条简单的经验法则:已经被导出到其他库中的历史记录此后一般应被视作不可改变的。
 
这样,一旦你向你的公共代码库服务器推送了一组变更,这些变更就不应该被重写了。如果你尝试推送无法进行快进合并(例如,那些没有共享同一变更历史的改变)的变更,Git会试图强制执行这条规则。对这种检查进行重写是可能的,并且有时重写一个导出源码树可能是必须的。在linux-next中通过在树间移动变更集(changesets)来避免冲突就是一个例子。不过这种行为应该是不常发生的。这也是开发工作要在私有分支上(必要时可以进行历史重写)完成并只是在其处于开发后期时才移到公共分支的原因之一。
 
随着主线版本(或即将到来的其他基于一组变更的源码树)的推进,人们总愿意合并那些树以保持走在开发的最前沿。对于一个私有分支来说,换基(rebasing)可以作为一种跟上另外一棵源码树开发进度的简单方法,但一旦源码树已经对外发布,换基这种方法就不再适合。一旦如此,就必须进行全量合并(full merge)。偶尔的合并很有意义,但过于频繁的合并可能会导致修订历史不必要得混乱。针对这种情况的建议是不要频繁地合并,通常只在特定发布点(例如,一个主线的-rc版本发布时)进行合并操作。如果你对特定的变更感到紧张不安,那么你可以一直在私有分支上进行测试合并。git的"rerere"工具在这种情况下十分有用;它会记住合并时的冲突是如何被解决的,这样你就无需再做一遍这个工作了。
 
关于类似git这样的工具的一个最大的抱怨是:补丁从一棵树到另一棵树的大量的迁移使得许多欠考虑的变更很容易通过评审雷达的盲区而进入内核主线。当内核开发者看到这种事情发生时都会十分不满;搭建一棵包含了未评审或离题补丁的源码树很可能会对以后你的源码树被内核主线合并的资格产生影响。这里引述Linus的一段话:
 
   你可以给我发送补丁,不过对我来说是从你那里拉出一个git补丁。我需要知道你十分清楚你自己正在做什么,并且我需要有能力在无需手工逐个检查每个变更的情况下信任你所做的这些工作。(http://lwn.net/Articles/224135/).
 
为了避免这类情况,请确保一个特定分支里面的所有补丁都紧扣相关主题;一个"驱动程序修复"分支不应该对核心内存管理代码进行修改。并且,更为重要的是,不要使用git树绕过评审过程。不时地将源码树的概要发到相关的邮件列表中,并且当时机合适时,请求将你的源码树中的变更包含到linux-next中。
 
如果当其他人开始向你的源码树发送补丁时,不要忘记评审这些补丁代码。同时,也要保证你维护着正确的作者身份信息;在这方面git的"am"工具做得最好,不过对于那些通过第三方转发给你的补丁,你需要为补丁增加一个"From:"行。
 
当提出"拉出"请求时,请确保提供了所有相关信息:你的源码树的位置,从哪个分支拉出,以及此次拉出将导致哪些改变。在这方面,git的"request-pull"命令很有帮助;这个命令会将请求按照其他开发者所期望的那样进行格式化,并且还会执行检查以确保你记得已经将那些改变提交到公共代码树服务器上了。
 
7.2、评审补丁
 
很多读者肯定会反对将本章标题命名为"高级主题",因为即便是刚入门的内核开发者也应当评审补丁。的确,没有比审查其他人发布的代码更好的方式去学习在内核环境下如何编程了。此外,评审者永远供不应求;通过审查代码,你可以对整个开发过程作出重要的贡献。
 
评审代码可能是一件令人胆怯的事情,特别是对于内核开发新手们,他们对于那些经验丰富的开发者所公开提出的代码质疑很可能会感到紧张不安。不过,即使是经验最为丰富的开发者所编写到的代码也可能有改进的余地。也许对评审者(所有评审者)最好的建议是:用询问而不是批评来表达评审意见。问"在这条路径上这个锁是如何被释放的?"总是会比"这里的锁用错了"收到更好的效果。
 
不同的开发者会从不同的角度去评审代码。一些人主要关注代码风格以及是否代码行伴有结尾空白。其他人会主要关注这个补丁所实现的改变对与内核整体来说是好事还是坏事。然而,还有其他一些人将检查有问题的锁、过度使用栈、潜在的安全问题、在其他地方发现重复代码、是否有充足的文档、对内核性能的不利影响、用户空间ABI变化等。如果能够促使更好的代码进入内核,那么所有类型的评审都是受欢迎的并且是值得花时间做的。
 
8、更多信息
 
Linux内核开发以及相关主题的信息来源有很多。这里面首当其冲的应该是可以在发布的内核源码包中找到的Documentation目录。顶层的HOWTO文件是一个重要的起点;SubmittingPatches和SubmittingDrivers同样是所有内核开发者都应该阅读的重要文档。许多内核内部API都使用kerneldoc机制进行了文档化;"make htmldocs"或"make pdfdocs"可用于生成HTML或PDF格式(但很多Linux发行版中包含的TeX版本运行时遇到内部限制,因此也无法正确地处理这里的文档)的内核文档。
 
各种讨论内核开发细节的网络站点。作者这里将http://lwn.net作为一个内核开发信息来源推荐给大家;许多关于特定内核主题的信息都可以通过LWN内核索引找到:
 
http://lwn.net/Kernel/Index/
 
除此之外,一个对内核开发者有价值的资源是:
 
http://kernelnewbies.org/
 
有关linux-next源码树的资料汇集在:
 
http://linux.f-seidel.de/linux-next/pmwiki/
 
当然,大家不应该忘记http://kernel.org,这里可是内核发布版本信息的最终位置。
 
下面是一些关于内核开发的书籍:
  * Linux Device Drivers(译注:其中译版为《Linux设备驱动程序》), 3rd Edition (Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman). 在线版本在http://lwn.net/Kernel/LDD3/。
 
  * Linux Kernel Development (Robert Love)(译注:其中译版为《Linux内核设计与实现》)。
 
  * Understanding the Linux Kernel (Danial Bovet and Marco Cesati)(译注:其中译版为《深入理解Linux内核》)。
 
但所有这些书籍都有一个共同的不足:在它们上架时往往有些过时,并且它们上架已经有一段时间了。不过,在这些书中我们仍然可以找到很多有价值的资料。
 
Git的文档可以在下面网址上找到:
 
http://www.kernel.org/pub/software/scm/git/docs/
 
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
 
9、结论
 
恭喜每一个读完这篇冗长文档的人。希望本文可以为你对Linux内核的开发过程以及如何加入此过程的理解提供有用的帮助。
 
最后,最重要的是参与。任何开源软件项目只不过是其所有贡献者所做事情的总和。Linux内核项目进展如此迅速,质量如此之好,都是因为有数量可观的开发者的帮助,他们的工作都是为了创建一个更好的内核。Linux内核就是一个由成千上万人为了一个共同的目标而一起奋斗而完成的一个最好的例子。
 
虽然内核项目总是能受益于一个更为庞大的开发者基础,但那里也总是有更多的工作要去做。但同样重要的是,在Linux生态系统中的其他大多数参与者也能从对内核的贡献中受益。让代码进入主线是更高代码质量、更低的维护和发行成本、对内核开发方向的更高层次的影响以及更多其他事情的关键。这是一个所有参与者共赢的局面。发动你的编辑器并加入我们吧;你会受到热烈欢迎。
 
(全文翻译结束)
如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats