Linux认证:UbuntuNativePOSIX线程库
在2.6版本以前发布的Linux内核中,Linux线程库叫做LinuxThreads,为glibc2.0以后的GNU C库所支持。该库虽然使用了POSIX API,但是并不真正遵循POSIX标准。从2.6内核开始,Linux引入了NPTL。它比LinuxThreads在性能上有了很大的提高,也更遵循 POSIX标准。但是,仅仅使用2.6内核并不等于使用了NPTL。尽管有些发行版会同时携带NPTL和LinuxThreads, 但所有现代的Linux发行版都缺省携带NPTL。
用下面的命令可以查看你的系统上正在使用的POSIX实现:
编辑请注意,该代码中需要翻译的内容为:
(1)“This was returned from SUSE 9.1 installation”翻译成“这是SUSE 9.1返回的结果”
(2)“This was returned from Fedora 2.6.9-1.667 Instatllation”翻译成“翻译成“这是Fedora 2.6.9-1.667返回的结果”
(3)“This was returned from an old RedHat installation” “翻译成“这是一个老版本的RedHat返回的结果”
$ getconf GNU_LIBPATHREAD_VERSION
$ getconf GNU_LIBPATHREAD_VERSION
$ getconf GNU_LIBPATHREAD_VERSION
用下面的方法可以查看正在使用的Linux发行版是用什么编译工具编译链接的。
要找到/bin/ls链接的libpthreads库,如下:
(代码)(P81倒数第14行)
$ ldd /bin/ls |grep libc.so.6
从上面的输出内容可以看到,libc.so.6是和“Native POSIX Threads Library by Ulrich Drepper”一起链接的。
NPTL实现了一对一的线程模型;也就是说,一个用户线程对应一个内核线程。NPTL也实现了POSIX进程间的同步原语,而且线程选项PTHREAD_PROCESS_SHARED也被明确支持了。
1 最大线程数
在Linux上一个应用程序能够创建的线程最大数量在不同的发行版上是不同的。运行在2个CPU 2GB内存上的SUSE9.1在pthread_create返回EAGAIN错误前允许创建16317个线程。EAGAIN错误的意思是说应用程序可能超过了系统的某些限制。该应用程序创建线程的栈大小为16384,这是创建线程时允许的最大栈大小。在把栈大小设置为16384前,该应用程序会在创建第 1021个线程时失败,并返回错误码ENOMEM。任何情况下,8000到16000个线程已经足以满足任何应用程序的需求。
要在Linux上创建大数量的线程,需要先做下面的事情:
1. 创建正确的栈大小(注释17);
2. 检查ulimit(可以输出内存、栈大小限制等的工具),修改对应项或编辑/etc/security/limits.conf文件。
第4、5、6章更详细的讲述了POSIX线程的内容,以及它与NPTL的区别。
2 国际化(I18N)(注释18)和本地化
I18N对项目移植会有多大的影响在很大程度上取决于待移植的应用程序。如果一个应用程序仅需要一些简单的消息目录(message catalogue)转换、时期和时间显示,或使用正则表达式进行简单的文本串查找,那么把这些功能从UNIX平台移植到Linux上还是比较容易的。但是,如果该应用程序进行了复杂的文本分析,就像有时在文本编辑器理使用的那样,移植这些内容将会是比较困难的,见下一段的分析。
Linux遵循ISO对标准locale名称的命名规范,[locale]_[territory].[codeset]。其中,locale 由两个字符组成,代表言语;territory由两字符组成,代表国别。例如en_US.iso885915和zh_CN.gb18030。但是,每个系统上可用的locale和locale的内容是各不相同的。移植使用了locale复杂应用的应用程序可能需要学习具体的语言规范和翻译规则,甚至需要修改Linux上已有的locale才能使移植后的应用程序像在源系统上那样运行。
表3-4列出了支持的GNU libc国际化函数。linux.ctocio.com.cn/imagelist/2009/168/5bb91ws241x2.pdf" target=_blank>表3-4.pdf
在Linux上,可以使用locale –a命令察看系统上安装的locale,解码文件可以在/usr/share/locale/locale.alias里找到。
3 iconv支持
Linux提供了iconv(1)工具把传统的字符串编码转换统一码(unicode)。可以用iconv –list命令得到当前Linux上实现的字符串编码列表。
有些时候,仅使用iconv工具转换字符串编码是不够的。有些应用程序,例如邮件发送器、网页接口,需要在两种不同的编码间互相转换。GNU libc提供了内部字符串编码(unicode,统一码)和外部字符串编码(传统编码)间互相转换的功能。
程序3-4给出了如何使用libicon API的示例。
(代码)(P85-87)
编译代码:
(代码)(P87倒数第6行)
$ gcc iconv_samp.c –o iconv_samp
使用生成的程序来转换一个输入文件:
(代码)(P87倒数第4行)
$ ./iconv_samp WINDOWS-1256 ISO_8859-16 < input-file
4 如何创建消息目录(message catalog)(注释19)
消息目录是一个文件,用来把应用程序语言相关的输出内容转换成系统locale设置的语言。程序3-5给出了一个在Linux上如何用GNU xgettext和msgfmt工具创建消息目录的示例。
(代码)(P88第3行)
该例中,我们要以西班牙语输出本书的书名和作者。首先,我们对示例程序运行xgettext:
(代码)(P88第22行)
$ xgettext hello.c
这会生成一个叫message.po的文件:
(代码)(P88第24行)
$ cat message.po
编辑文件message.po,对每个要翻译的消息修改msgstr,并编辑charset(如果在运行xgettext前没有设置的话)。然后对message.po文件运行msgfmt命令。文件my_messages.mo指向的是bindtextdomain()设置的域。
(代码)(P89第16行)
$ msgfmt –v –o my_message.mo message.po
为运行示例程序,我们在本地目录中为西班牙语(哥斯达黎加)创建一个目录(不使用缺省的/usr/lib/locale目录,因为我们没有root权限):
(代码)(P89第20行)
$ mkdir –p locale/es_CR/LC_MESSAGES
然后把my_message.mo移到该目录下:
(代码)(P89第22行)
$ mv my_message.mo locale/es_CR/LC_MESSAGES
为环境变量LC_MESSAGES输出正确的值,并运行示例程序:
(代码)(P89第25行)
$ export LC_MESSAGES=es_CR
$ ./hello
至此,我们成功地在Linux上创建了一个消息目录文件。