监理公司管理系统 | 工程企业管理系统 | OA系统 | ERP系统 | 造价咨询管理系统 | 工程设计管理系统 | 签约案例 | 购买价格 | 在线试用 | 手机APP | 产品资料
X 关闭
南昌OA信息化

当前位置:工程项目OA系统 > 泛普各地 > 江西OA系统 > 南昌OA系统 > 南昌OA信息化

Linux遭遇扩展性问题

申请免费试用、咨询电话:400-8352-114

文章来源:泛普软件

使用真正大型机器的乐趣,一方面在于能够比别人更早在可扩展性方面发现新的惊奇,所以使用SGI高性能计算机的人常常比我们许多人享有更多的乐趣。他们最近的发现与内核线程的数量有关: 在4096路系统上,Linux内核线程的数量导致内核出现了令人关注的一些行为。

发现问题

首先他们发现:即使使用默认的配置,也启动不了内核。Linux系统在任何一个特定的时间,活动进程通常限制在32768个。运行过ps命令的人都会注意到: 内核线程在占用数量越来越多的内存插槽。单处理器桌面系统可能在运行其中的39个活动进程。实际上,如今一个典型的系统上有足够多的内核线程,以至这些线程会占满4096路机器上的全部空间,甚至更多。这个问题比较容易得到解决,只要提高处理器数量的限额。不过,这样一来情况变得比较有意思了。

对系统上的其他每个进程(包括内核线程)来说,init进程是最终的父进程。所以在大型系统上,init有许多子进程。这些子进程位于一个很大的链表(linked list)上。该链表由诸多函数来搜索,其中包括wait()的变种版本。如果正在搜索中的进程接近链表末端,那么这个搜索需要花费很长时间。一是因为大多数内核线程是长期线程,二是因为新进程被放在链表末端,所以某次搜索很可能确实会寻找末端的某个进程。

然后把某个模块装入内核。当新模块进行链接时,模块装入过程就会调用stop_machine_run(),该函数会为系统上的每个进程创建高优先级的内核线程。该线程就会获取分配给它的CPU,然后只是闲置在那里,直到被告知退出;尽管所有CPU以这种方式被搁置起来,但链接过程照常执行。即便在最好的时候(即线程数量不多的时候),调用stop_machine_run()这样的函数也是有点不合常理,更何况对一个拥有4096路处理器的系统而言,stop_machine_run()会创建4096个线程,每个线程都会进入到init的子链表的末端;每个线程等到需要清理时,都必须进行搜索。结果就是,系统在很长一段时间过后才会停机。

解决办法

有人可能认为,拥有这么大系统的人根本不应该装入模块,但可能会受到来自用户社区的反对。所以需要找到其他的解决方案。有关报告提供了一种简单的补丁,可以把现有的进程转移到子链表的始端。这种变化解决了眼前的问题,因为它可以通过搜索这些子进程就能找到它们,不必遍历不会去任何地方的所有长期进程。

Linus有几个变通办法。办法之一就是为僵尸进程(zombie process)建立不同的链表,从而完全不需要这种搜索。另一个办法就是停止让内核线程成为init进程的子进程,因为在任何情况下,它们与用户空间都没有多大关系。但一些开发人员认为,真正的解决方案也许在于开始减少内核线程的数量。

导致内核线程大量创建的最主要原因无疑是工作队列。默认情况下,工作队列会为系统上的每个CPU创建一个线程。有些情况能够得益于多个线程和CPU局部性(CPU locality),但毫无疑问也有许多情况下不需要所有这些线程。清除这些线程有助于解决部分扩展性问题; 另一个好处就是,这可以让ps列表显得整洁一些。

在许多情况下,工作队列可能根本没有必要。相反,内核子系统可能完全使用“一般的”keventd工作队列(作为events/n线程来运行)。使用keventd内核线程存在一些问题,包括无限制延迟以及可能性很小的死锁,不过在许多情况下,它的工作效果足够好。

在其他情况下,使用线程很有必要。涉及长时间延迟的任务是一个例子; 使用kevented运行延迟时间好几秒的函数被认为是不恰当的。需要复杂上下文的工作也会得益于其自己的线程。不过在许多情况下,这些线程在一些工作实际完成之前并不需要创建。大多数系统上迅速运行ps命令可以显示与错误处理、异步I/O、蓝牙及更多方面有关的线程。按照当前方式,这些线程在启动时(或者模块装入时)创建,其中许多线程在系统关闭之前可能根本不做任何实际工作。创建线程的成本很低,所以许多这些线程可以在需要时创建而成。

这方面恐怕需要进行一些真正的改进。需要的只是有人、有时间、有动力来做这项工作。与此同时,使用4096路处理器系统的人可能需要打上一两个补丁。

链接:进程与线程

可执行文件由指令和数据组成。进程就是在计算机上运行的可执行文件针对特定的输入数据的一个实例,同一个可执行程序文件如果操作不同的输入数据就是两个不同的进程。

线程是进程的一条执行路径,它包含独立的堆栈和CPU寄存器状态,每个线程共享其所附属的进程的所有的资源,包括打开的文件、页表(因此也就共享整个用户态地址空间)、信号标识及动态分配的内存等等。线程和进程的关系是:线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一物理内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除。

Linux内核只提供了轻量进程的支持,限制了更高效的线程模型的实现,但Linux着重优化了进程的调度开销,一定程度上也弥补了这一缺陷。目前最流行的线程机制LinuxThreads所采用的就是线程-进程“一对一”模型,调度交给核心,而在用户级实现一个包括信号处理在内的线程管理机制。

在Linux的“一对一”模型中,用一个核心进程(轻量进程)对应一个线程,将线程调度等同于进程调度,交给核心完成,而其他诸如线程取消、线程间的同步等工作,都是在核外线程库中完成的。因此可以把进程看作一组线程,这组线程拥有相同的线程组号(TGID),这个TGID就是这组线程序所附属的进程的ID号,每个线程的ID号就是我们用ps命令所看到的LWP号。(ccw)
 

发布:2007-04-22 09:57    编辑:泛普软件 · xiaona    [打印此页]    [关闭]
南昌OA系统
联系方式

成都公司:成都市成华区建设南路160号1层9号

重庆公司:重庆市江北区红旗河沟华创商务大厦18楼

咨询:400-8352-114

加微信,免费获取试用系统

QQ在线咨询

泛普南昌OA信息化其他应用

南昌OA软件 南昌OA新闻动态 南昌OA信息化 南昌OA快博 南昌OA行业资讯 南昌软件开发公司 南昌门禁系统 南昌物业管理软件 南昌仓库管理软件 南昌餐饮管理软件 南昌网站建设公司