红联Linux门户
Linux帮助

剖析Linux 2.6内核移植--超线程篇

发布时间:2006-09-21 10:32:56来源:红联作者:MORR
  应用2.6内核超线程模式

  对于大多数应用软件开发者来说,Linux 2.4和2.6内核家族间的大部分差异对它们没有直接的影响。大多数内核变化只是为了提高系统性能而已。但也有例外,对某些应用软件而言,内核和系统的变化对它们的推广和它们对其它进程和线程的管理都具有一定的影响。

  2.6内核为用户带来了一种新的、改进的超线程模式。这种模式是通过NPTL(Native POSIX Thread Library)实施的。新的超线程模式的采用对于开发人员、系统运行时间库(如GNU C库)、共享应用软件库等有着非凡的意义。本文将介绍基本的超线程概念,讨论已有的Linux超线程模式,并着重指出在2.6内核下如何修改已有多线程应用软件。

  超线程技术

  在Linux之类的多进程操作系统中,一个进程生成另一个进程是最基本的概念。最典型的例子是外壳程序,如Bash外壳程序。它是一个标准的Linux命令翻译程序。外壳程序根据用户的命令执行相应的应用程序,可以直接启动多个命令并等待它们完成,也可以将多个命令分开同时执行。

  一个进程通常可以通过一组fork()和exec()函数调用来生成新的进程。初始进程调用fork()函数,产生一个子进程。子进程继承了母进程的整个执行环境。fork()函数调用将子进程的进程标识(PID)反馈给母进程,同时还包括子进程中的PID。然后,子进程使用exec()函数调用来执行其它的命令,改变继承来的执行环境。同时,母进程或者迅速退出,或者等待子进程回到其初始状态。

  Linux超线程模式

  Linux 2.6内核以前所有版本的标准Linux超线程库被称为LinuxThreads。这种库可以与不低于GLIBC 2.0版本GNU C库一起工作,并且与POSIX兼容。

  在LinuxThreads和Native POSIX Thread Library(NPTL)源代码的编译过程中,产生的主要库是libpthread.so和libpthread.a。为此,LinuxThreads和pthreads名称过去可以互换使用。但是引入NPTL后,两者极易发生混淆。本文使用LinuxThreads和NPTL以便明确区分两个超线程库和它们的功能。

  LinuxThreads拥有不同的性能、可伸缩性和可用性限制。LinuxThreads针对单一进程可产生的线程数通过一个编译器设置。此外,它还使用一个进程管理器协调每个进程产生的所有线程间的关系。这样会大大增加线程建立和消除占用的资源。尽管基本上每个线程都有独立的进程ID,但信号的处理仍是在各个进程中完成的。由于种种原因,在LinuxThreads实施过程中,同时产生并工作的线程数量常常会受到限制。这些原因包括内核与用户空间线程间的不对称关系,缺少线程间通信和分享资源所需的线程同步原语等。

  Linux的另一超线程模式是IBM公司的下一代POSIX线程(NGPT)项目。它是一个与LinuxThreads套件一起工作的外部超线程库。但是它可以提供额外的POSIX支持和优于标准LinuxThreads套件的性能。NGPT套件可用于Linux2.4和更早的内核,由于新超线程模式的产生,其应用范围越来越小。

  NPTL自从出现2.5内核后便开始逐渐代替LinuxThreads和NGPT。NPTL为Linux系统提供更高性能的超线程支持,并且可提供多线程企业应用软件所需的基本功能,此外还可提供高容量、高加载量的网络和邮件服务器等。NPTL的开发是2.5内核开发进程的一部分,并且与Linux运行时元件(如GLIBC)集成在一起,具备了众多优势的NPTL是未来Linux线程的发展方向。

  一些Linux系统生产商(如Red Hat公司)已开始向旧版本内核追加NPTL,甚至通过一个环境变量为特定的可选进程创建超线程环境。在支持此功能的系统中,变量可以通过下面的命令来设置:

[code]# export LD_ASSUME_KERNEL=2.4.1[/code]

  对于那些原本依靠LinuxThreads模式的已有应用软件来说,要想继续在NPTL环境下工作,这是一个比较聪明的办法,但同时也是一个权宜之计。为了能更好的利用NPTL的设计和性能优势,用户需要对使用超线程模式的现有应用软件的代码进行升级。
文章评论

共有 4 条评论

  1. hitach 于 2006-09-22 11:14:42发表:

  2. MORR 于 2006-09-21 10:34:53发表:

      总结

      修改计算机运行的内核并不是件容易的事,但是它也不是不可能完成的任务。以上五篇文章中,我们着重介绍了2.6内核设置中遇到的主要问题、升级硬件驱动程序、移植桌面和定制系统以及升级应用软件。TimeSys公司的2.6 Reference Distribution是第一款应用于PPC系统的Linux套件。诸如TimeSys公司的TimeStorm IDE和TimeStorm Linux系统开发套件(LDS)之类的高质量商业软件可以帮助我们移植所有的Linux内核、硬件驱动程序、应用软件。此外,它们还可以帮助我们对系统进行配置,以便充分发挥2.6内核、升级套件、穿线技术等软件技术的作用。

      Linux作为开放系统运动中最耀眼的明星,积极投身于软件产业的变革。Linux内核作为所有Linux系统的核心,在发展过程中不断地引入新技术,改善性能、可伸缩性、技术支持和可用性。2.6内核拓展了Linux系统的应用范围,从PDA、进程控制系统、机顶盒到企业服务器处处都能看到它的身影。Linux系统的成本、动力和技术支持优势在今天的商业市场和飞速发展的技术环境中显得更加明显。

  3. MORR 于 2006-09-21 10:34:20发表:

      为NPTL升级应用软件

      2.4内核的超线程支持和NPTL支持间的变化为设计和性能的提高提供了广阔的改进空间。在2.4内核下,NPTL与POSIX规格的适应程度要比与LinuxThreads套件的适应程序高得多。NPTL还支持诸如mutexes之类的功能。最后,NPTL要比2.4内核的超线程支持更有效。

      在向NPTL移植过程中,用户需要对应用软件逻辑作更复杂的修改。这些修改与NPTL对POSIX信号和信号处理的支持有关。LinuxThreads实施一般性的Unix型线程,但是它却受各种实施细节的限制。因为NPTL是一种与POSIX相适应的超线程实施方案,所以它在进程间信号处理和线程间信号处理方面表现得较为优秀。在NPTL中,信号可以由一个线程传给另一线程,而不只是进程间的传递。信号也可以使用参数来完成线程间的信息传递。

      在使用NPTL时,用户还需要对识别具体线程的现有代码进行修改。在LinuxThreads下,每个线程都拥有惟一的进程ID(PID)。而现在,母进程下的各个线程都共享同一PID,因此getpid()函数将为进程中的所有线程返回同一PID。在NPTL下,一个线程的线程ID在使用时必须是唯一的,这样才能对每个线程进行正确的识别。

      对线程ID和进程ID进行的修改还意味着进程产生的方式现在需要针对线程而进行。例如,exec()函数目前可以对线程进行操作,因此一个线程可以继承调用者的PID。只有当整个进程结束时,多线程进程的母进程才知道某一子进程已经执行完毕。有关线程的变化还会对相关fork()调用产生影响。例如,在pthread_at_fork()函数中登记的函数在vfork()发生时将无法再继续运行。

      除了对线程识别的内部构件进行修改外,NPTL废除了LinuxThreads的管理者线程的概念,简化了进程和线程间的关系。这些也许需要对应用软件做适当的修改。

      最后,使用新超线程库意味着在LinuxThreads可以使用的一些超线程函数在NPTL下将无法继续使用。例如pthread_kill_other_threads_np()函数便无法继续使用。该函数将的作用是激活与POSIX相适应的exec()函数,而在NPTL下,exec()函数无法再与POSIX相适应。

  4. MORR 于 2006-09-21 10:33:43发表:

      应用软件的重编译

      尽管有许多应用软件从2.4内核到2.6内核移植过程中不需要重新编译,但是大多数多线程应用软件的NPTL附加技术需要进行略微的修改。

      那些需要重新编译的应用软件也许会受到升级编译程序的影响。这些编译程序一般都包含在基于2.6内核的Linux套件中,例如TimeSys Linux系统。TimeSys在推出2.6 Reference Distributions的同时捆绑了GCC的3.3.2版本的C和C++编译程序,并使用升级版本的binutils套件弥补标准Linux工具链的不足。

      使用基于2.6的内核并不意味着用户已自动使用NPTL。为了决定系统使用的超线程库,用户可以执行下面的命令,对GNU_LIBPTHREAD_VERSION环境变量进行检测,如下所示:

    [code]# getconf GNU_LIBPTHREAD_VERSIONlinuxthreads-0.10
    If your system uses the NPTL, the command would return the value of NPTL
    that your system was using,as in the following example:
    # getconf GNU_LIBPTHREAD_VERSIONnptl-0.60[/code]

      如果用户正在建立适用于2.6内核的工具链,那么必须确定已经在2.6内核上建立了拥有NPTL技术支持的“工具链”。此外,用户还需要较新的C语言库源代码。例如,如果用户正在建立拥有NPTL支持的GBLIC,那么就要使用2.3.3版本以上的GBLIC源代码。为GBLIC提供NPTL支持的过程与提供LinuxThreads支持的过程十分相似。不同的是在设置GBLIC时,使用“--enable-add-ons=nptl”设置选项,而不是“--enable-add-ons=linuxthreads”。用户还需要一个新版本的GCC(3.3.2或更高版本)和支持框架信息调用(CFI)指令的binutils(2.14.90.0.7或更高版本)。

      一般情况下,如果用户的应用软件使用较早版本的GCC进行编译,用户也许会注意到报警信息、源代码尺寸等不同之处。此外,GCC编译程序和剩余工具链提供的选项也不尽相同。当用户在对嵌入式应用软件进行重新编译时,必须了解代码尺寸有增大的潜在趋势。用户也许需要充分利用额外或新的优化选项,以便在资源有限的环境下,继续适应现有的应用软件。版本越新的GCC越能适应各种C或C++规格,并提高了对应用软件代码的要求。一般情况下,从升级编译程序中获得的新报警信息对消除潜在缺陷是十分有用的。