风声竹影 的个人资料听风竹轩的书架日志列表网络 工具 帮助

日志


9月30日

Linux文件类型(精品)

  如果您有Dos和Windows经验,就大概知道系统存在若干类型的文件,如系统文件、只读文件、隐含文件等。在Linux/Unix下,文件类型远比Dos/Windows系统多样和复杂。本文以RedHat Linux为例,旨在使读者对Linux下的文件类型有更多的了解。文中的多数内容,对其他发行版的Linux以及Aix、Solaris、 Freebsd等操作系统也同样正确。

image

  Linux下可以用ls –l 命令来判断文件类型,如上 图所示。可以依据第一列中的10个字符来判断。

  • -rw-r—r—指明了1.txt文件是一个普通文件,1.txt和myprog04文件都是普通文件。以”-“开头的都是普通文件,而以”d”开头的是目录文件。
  • brw-rw---- 指明了/dev/sda1是一个块设备(Block Device)文件。以”b”开头的文件都是块设备文件。•
  • crw-rw----指明了/dev/lp0是一个字符设备(Chartacter Device)文件,以”c”开头的文件都是字符设备文件。
  • srwxrwxrwx 指明了/var/lib/mysql/mysql.sock是一个socket文件。以””开头的文件都是socket文件。
  • prwxr—r--指明了了mypipe 是一个管道文件。管道文件的一个属性是”p”。
  • lrwxrwxrwx 指明了softlinkof1.txt 是一个软链接文件(或称符号链接文件),该文件指向了1.txt。以”l”开头的文件是软链接文件。
  • -rw-r—r—开头的hard_link_of_1.txt看上去是个普通文件,但它实际上是一个硬链接文件。
  • -rwsr-xr-x指明了myprog01是一个setUid的可执行文件,这是根据第四个字符”s”判断的。
  • -rwxr-sr-x指明了myprog03是一个setGid的可执行文件,这是根据第七个字符中的”s”判断的。
  • -rwsr-sr-x指明了myprog02是一个setUid加setGid的可执行文件,这是根据第四个和第七个字符中的”s”判断的。
  • drwxrwxrwt 中的第一个”d”字指明了tmp文件是一个目录,最后一个字符”t”指明了该目录被设置了粘着位。   一、设备文件

  Linux下的/dev 目录中有大量的设备文件。主要是块设备文件和字符设备文件。
  块设备文件

  在过去,在添加新磁盘后,往往需要手动增加块设备文件。现在通常我们不需要手动增加块设备文件,运行一下service kudzu start ,系统就会自动为您配置相应的设备。块设备的主要特点是可以随机读写,而最常见的块设备就是磁盘,如/dev/hda1 、/dev/sda2、/dev/fd0等。

  字符设备文件

  同块设备一样,我们一般都可以用service kudzu start命令来自动增加、删除或修改字符设备。最常见的字符设备是打印机和终端,他们可以接受字符流。

  /dev/null是一个非常有用的字符设备文件,送入这个设备的所有东西都被忽略。如果将任何程序的输出结果重定向到/dev/null,则看不到任何输出信息。甚至于,您可以将某一用户的shell指向/dev/null 以禁止其登陆。

  管道设备文件

  管道设备文件有时候也被叫做FIFO文件(FIFO是先进先出的意思),从字面上理解,管道设备文件就是从一头流入,从另一头流出。通常我们会在其中做一些工作,以达到我们“吃的是草,挤出来的是奶”的目的,管道文件也有其妙用。

  以前,Unix系统对文件的最大用量用2GB的限制,虽然现在新版本的Linux、Solaris、FreeBSD等不再有此限制,但处理大文件的需求仍然存在,假设您想用镜像(dd命令)的方式来备份一个容量为20GB分区的分区,就会产生一个20GB的文件,根据您磁盘实际的使用状况,这个文件在压缩后可能只有数MB到数GB,我们可以建立一个管道文件来自动实现这个压缩过程。

  [root@linux236 root]# mknod mypipe p
  [root@linux236 root]# ls -l mypipe
  prw-r--r-- 1 root root 0 Aug  5 23:27 mypipe
  [root@linux236 root]#

  在这里,我们建立了一个叫mypipe的管道文件,用ls -l 命令可以看到它的属性是prw-r--r--,用下面的组合命令实现镜像和压缩:

  [root@linux236 root]# compress < mypipe > sda6.img.Z &
  [root@linux236 root]# dd if=/dev/sda6 of=mypipe
  [root@linux236 root]# ls sda6.img.Z
  sda6.img.Z

  第一个命令使得从mypipe管道中流出的文件被压缩为sda.img.Z文件,注意这个命令的结尾必须使用"&"符号。第二个命令将 /dev/sda6分区中的资料道入管道文件mypipe,换句话说,/dev/sda6分区中的数据进入管道,而压缩文件sda6.img.Z文件从管道中流出。

  在导出Oracle、DB2等大型数据库时等经常会生成很大的文件,熟练的数据库管理员往往会选择通过管道进行压缩的方式,对于Oracle数据库,我们可以使用下边的组合命令:
  这样,就会将Oracle导出的内容直接压缩成为expdat.dmp.Z文件。

  compress < mypipe > expdat.dmp.Z &
  exp userid=system  file=mypipe owner=scott
第二章 链接文件

  链接文件有点类似于Windows 的所谓快捷方式,但并不完全一样。链接有两种方式,软链接和硬链接。

  软链接文件

  软链接又叫符号链接,这个文件包含了另一个文件的路径名。可以是任意文件或目录,可以链接不同文件系统的文件。链接文件甚至可以链接不存在的文件,这就产生一般称之为"断链"的问题(或曰“现象"),链接文件甚至可以循环链接自己。类似于编程语言中的递归。

  [yaoyao@linux236 yaoyao]$ ls -l
  total 0
  lrwxrwxrwx 1 yaoyao yaoyao  5 Aug  6 17:39 1.txt -> 3.txt
  lrwxrwxrwx 1 yaoyao yaoyao  5 Aug  6 17:38 2.txt -> 1.txt
  lrwxrwxrwx 1 yaoyao yaoyao  5 Aug  6 17:39 3.txt -> 2.txt

  上面的三个文件形成了一个递归,实质上没有任何作用。系统管理员应该避免系统出现断链或循环链接。

  用ln -s 命令可以生成一个软连接,如下:

  [root@linux236 test]# ln -s  source_file softlink_file

  在对符号文件进行读或写操作的时候,系统会自动把该操作转换为对源文件的操作,但删除链接文件时,系统仅仅删除链接文件,而不删除源文件本身。

  硬链接文件

  info ln 命令告诉您,硬链接是已存在文件的另一个名字(A "hard link" is another name for an existing file),这多少有些令人困惑。硬连接的命令是

  ln -d existfile newfile

  硬链接文件有两个限制

  1、不允许给目录创建硬链接;
  2、只有在同一文件系统中的文件之间才能创建链接。

  对硬链接文件进行读写和删除操作时候,结果和软链接相同。但如果我们删除硬链接文件的源文件,硬链接文件仍然存在,而且保留了愿有的内容。这时,系统就“忘记”了它曾经是硬链接文件。而把他当成一个普通文件。   三、setUid、setGid文件和带粘着位的目录文件

  在Linux/Unix下,有一种可执行文件被setUid,这使得任意使用者在执行该文件时,都绑定了文件拥有者的权限。就好像文件带了一把尚方宝剑一样,setUid文件通常用来提升使用者的权限.最有代表性的su命令.普通用户可以可以执行该命令,使自己升级为root。setUid命令的用法是:

  chmod 4755 your_program

  setGid 文件和setUid文件非常类似,它使得这使得任意使用者在执行该文件时,都绑定了文件所有组的权限.单独setGid的文件非常少用,通常都是即 setUid又setGid。不过和您猜想的可能有点不同。setUid+setGid通常并不是用来提升权限的,而是为了绑定某个特殊用户及其组的特殊权限,例如qmail 的外围软件vpopmail,就使用了一个setUid+setGid的程序vchkpw来校验用户名和密码。这个道理和Apache常常以nobody 用户运行一样。其目的是为了更加安全。

  setGid 命令的用法为
  chmod 2755 your_program

  通常使用命令
  chmod 6755 yourprogram

  来使得某可执行程序同时setUid和setGid

  全能的root用户当然可以任意setUid和setGid。但尚方宝剑不能用来假传圣旨,普通用户只能给属于自己的文件配置setUid或 setGid。由于setUid或setGid文件会使普通用户提升权限,谨慎的系统管理员通常会留意系统中有setUid或setGid文件的变化。减少安全隐患。

  在Linux下,/tmp是一个存放临时文件的目录,要求是对所有用户可写。但每个用户都只能删除自己拥有的文件。这种情况下,就可以把目录加一个粘着位。

  [root@yaoyao /]# ls -l |grep tmp
  drwsrwsrwt 9 root root 4096  8月7 10:50 tmp

  注意第是个字符"t",它代表了这个目录被设置了粘着位。

  我们自行建立一个abc的目录,使之具有和/tmp相同的特点

  chmod 777 abc
  chmod +t abc

  上述的个两个命令组合等同于下边的一个命令:

  chmod 1777 abc

  用ls –l 看abc 目录的属性如下:

  [root@yaoyao test]# ls -l

  总用量 4

  drwsrwsrwt 2 root root 4096  8月 7 11:32 abc

  和/tmp目录相同的需求往往在ftp服务器的upload 目录中也存在。可以用相同的方式处理。   四、socket 文件

  socket文件类似于管道,但它是在网络上面工作的。您到计算机就是靠它来做网络处理的。您可能听说过“Winsock”,那是 Windows 的套接口。我们在这里不深入谈有关套接口,因为如果您不写程序,您不会用到它,但如果您看到您系统里有个文件类型是s,您知道它是什么就行了。

  比如说mysql 运行的时候通常会产生一个socket文件。

  [root@yaoyao tmp]# ls -l /tmp/mysql.sock

  srwxrwxrwx 1 mysql mysql 08月 7 10:03 mysql.sock

  /tmp目录下还有一些socket文件,多半是运行Xwindows的时候产生的。

五、疑难杂症--删除不掉的文件

  “为什么有些文件以讨厌的减号("-")开头做文件名,无论如何都删除不掉,这到底为什么?",您可能听过您临桌的新手这样的叫喊过,希望同样的事情不会发生在您的身上,这个非常容易解决,您只要用带路径的方法就可以把他们删除了,假定一个文件名为"-abc",您可以用:

  rm ./-abc 或者
  rm /home/yaoyao/-abc

  命令将其轻松删除,另外您也可以用相同的方式用vi或者其他工具对他们进行修改。

  另一些文件看上去可能一切正常,但当您尝试删除的时候,居然也会报错,就象下边一样:

  [root@linux236 root]# ls -l 1.txt
  -rw-r--r-- 1 root root 0 Aug  5 23:00 1.txt
  [root@linux236 root]# rm -rf 1.txt
  rm: cannot unlink `1.txt': Operation not permitted   您是全能root用户,居然系统告诉您操作不允许,是Linux疯了么?当然不是,如果您会用lsattr命令,问题就有了答案。

  [root@linux236 root]# lsattr
  ---i---------- ./1.txt
  -------------- ./weiqi.ldif
  -------------- ./qi.schema

  秘密终于暴露了,在lsattr命令下,这个1.txt文件带有一个"i"的属性,所以才不可以删除。您现在可以用下边的一系列命令:

  [root@linux236 root]# lsattr 1.txt
  ---i---------- 1.txt
  [root@linux236 root]# chattr -i 1.txt
  [root@linux236 root]# rm -rf 1.txt
  [root@linux236 root]#

  成功了,这个属性专门用来保护重要的文件不被删除,通常的情况下,懂得用这几个命令的通常系统管理员有能力判断这个文件是否可以被删除。 如果您想给一个文件多加点保护,可以使用下边的命令:

  chattr +i filename

  命令,这样一来,想要删除这个文件就要多一个步骤。同时,这样的文件也是不可以编辑和修改的。只有root用户才能使用chattr命令。此命令可以在Linux ext2或ext3系统上使用。

  类似于Dos和Windows文件系统,不能随意删除的文件多半都有其道理,即使您知道如何删除,都应该三思而后行。

总结

  Linux/Unix系统管理是个复杂的工作,掌握和理解Linux/Unix文件类型是必备的基础之一。学习Linux/Unix没有捷径,必需通过大量的实践和努力学习。

剖析Linux系统中硬链接与软链接的区别

首先要弄清楚,在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号。文件属性保存在索引结点里,在访问文件时,索引结点被复制到内存在,从而实现文件的快速访问。

链接是一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法。Linux中包括两种链接:硬链接(Hard Link)和软链接(Soft Link),软链接又称为符号链接(Symbolic link)。

一、硬链接

硬链接说白了是一个指针,指向文件索引节点,系统并不为它重新分配inode。可以用:ln命令来建立硬链接。语法:

ln [options] existingfile newfileln[options] existingfile-list directory

用法: 第一种:为”existingfile”创建硬链接,文件名为”newfile”。第二种:在”directory”目录中,为 ”existingfile-list”中包含的所有文件创建一个同名的硬链接。常用可选[options] –f 无论”newfile”存在与否,都创建链接。-n 如果”newfile”已存在,就不创建链接。

下面举一些例子:

$ ls –il
13058 -rwx - - - - - - 1 longcheng longcheng 48 8月 5 16:38 file1
13059 -rwx - - - - - - 1 longcheng longcheng 57 8月 5 16:40 file2
$ ln file2 file2hard
$ ls –il
13058 -rwx - - - - - - 1 longcheng longcheng 48 8月 5 16:38 file1
13059 -rwx - - - - - - 2 longcheng longcheng 57 8月 5 16:40 file2
13059 -rwx - - - - - - 2 longcheng longcheng 57 8月 5 16:40 file2hard

注意在创建链接前,file1 显示的链接数目为1,创建链接后(1)file1和file1hard的链接数目都变为2;(2) file1和file1hard在inode号是一样的(3) file1和file1hard显示的文件大小也是一样。可见进行了ln命令的操作结果:file1和file1hard是同一个文件的两个名字,它们具有同样的索引节点号和文件属性,建立文件file1的硬链接,就是为file1的文件索引节点在当前目录上建立一个新指针。如下图,你可以删除其中任何一个,如rm file2 ,每次只会删除一个指针,

链接数同时减一,只有将所有指向文件内容的指针,也即链接数减为0时,内核才会把文件内容从磁盘上删除。当前目录逻辑结构:(不好意思图没有显示出来)。

还可以在不同目录,但同一文件系统中建立文件的硬链接。设file1、file2在目录/home/longcheng/dir1中,下面的命令,在/home/longcheng中建立file2的硬链接。

ln file2 /home/longcheng/file2hard

下面的程序,是将dir1目录中所有文件,在目录dir2中建立硬链接

$mkdir dir2$ln /home/longcheng/dir1/* /home/longcheng/dir2

如果使用了 ln –f existingfile newfile,如果newfile已经存在,则无论原来newfile是什么文件,只用当前用户对它有写权限,newfile就成为exisitngfile的硬链接文件。

尽管硬链接节省空间,也是Linux系统整合文件系统的传统方式,但是存在一下不足之处:(1)不可以在不同文件系统的文件间建立链接(2)只有超级用户才可以为目录创建硬链接。虽然很多树上说root用户可以创建,但是笔者在学习过程中发现即使是root用户也不能创建,我的系统是Redhat,内核 2.4、2.6都试过,在其他系统中不知道是不是可以。

二、软链接(符号链接)

软链接克服了硬链接的不足,没有任何文件系统的限制,任何用户可以创建指向目录的符号链接。因而现在更为广泛使用,它具有更大的灵活性,甚至可以跨越不同机器、不同网络对文件进行链接。

建立软链接,只要在ln后面加上选项 –s,下面举个例子

$ ls -il
13058 -rwx------ 1 longcheng longcheng 48 8月 5 16:38 file1
13059 -rwx------ 2 longcheng longcheng 57 8月 5 16:40 file2
13059 -rwx------ 2 longcheng longcheng 57 8月 5 16:40 file2hard
$ln –s file1 file1soft
$ls -il
13058 -rwx------ 1 longcheng longcheng 48 8月 5 16:38 file1
13059 -rwx------ 2 longcheng longcheng 57 8月 5 16:40 file2
13059 -rwx------ 2 longcheng longcheng 57 8月 5 16:40 file2hard
13061 lrwxrwxrwx 1 longcheng longcheng 5 8月 5 16:58 file1soft->file1

从上面链接后的结果可以看出来软链接与硬链接,区别不仅仅是在概念上,在实现上也是不同的。区别:硬链接原文件&链接文件公用一个inode号,说明他们是同一个文件,而软链接原文件&链接文件拥有不同的inode号,表明他们是两个不同的文件;在文件属性上软链接明确写出了是链接文件,而硬链接没有写出来,因为在本质上硬链接文件和原文件是完全平等关系;链接数目是不一样的,软链接的链接数目不会增加;文件大小是不一样的,硬链接文件显示的大小是跟原文件是一样的,这用强调,因为是等同的嘛,而这里软链接显示的大小与原文件就不同了,file1大小是48B,而file1soft是5B,这里面的5实际上就是“file1”的大小。

总之,建立软链接就是建立了一个新文件。当访问链接文件时,系统就会发现他是个链接文件,它读取链接文件找到真正要访问的文件。

在不同系统之间建立软链接、对目录建立链接,这里就不举例了,读者可以自己去尝试,我也是在不断实践中学习的。

当然软链接也有硬链接没有的缺点,因为链接文件包含有原文件的路径信息,所以当原文件从一个目录下移到其他目录中,再访问链接文件,系统就找不到了,而硬链接就没有这个缺陷,你想怎么移就怎么移;还有它要系统分配额外的空间用于建立新的索引节点和保存原文件的路径。补充一下:可以通过symlink来查看链接文件,可以用 man symlink来学习。

为什么硬链接不能指向目录

 linux系统中的硬连接有两个限制:不能跨越文件系统和不允许普通用户对目录作硬连接。至于第一个限制,很好理解,而第二个就不那么好理解了。 我们对任何一个目录用ls -l 命令都可以看到其连接数至少是2,这也说明了系统中是存在硬连接的,而且命令ln -d 也可以让超级用户对目录作硬连接,这些都说明了系统限制对目录进行硬连接只是一个硬性规定,并不是逻辑上不允许或技术上的不可行。那么操作系统为什么要进行限制呢?答案可能有两个。  先来说第一个,如果引入了对目录的硬连接就有可能在目录中引入循环,那么在目录遍历的时候系统就会陷入无限循环当中。也许您会说,符号连接不也可以引入循环吗,那么为什么不限制目录的符号连接呢?原因就在于在linux系统中,每个文件(目录也是文件)都对应着一个inode结构,其中inode数据结构中包含了文件类型(目录,普通文件,符号连接文件等等)的信息,也就是说操作系统在遍历目录时可以判断出符号连接,既然可以判断出符号连接当然就可以采取一些措施来防范进入过大的循环了,系统在连续遇到8个符号连接后就停止遍历,这就是为什么对目录符号连接不会进入死循环的原因了。但是对于硬连接,由于操作系统中采用的数据结构和算法限制,目前是不能防范这种死循环的。 在说明第二个原因之前,我们先来看看文件的dentry结构在系统空间中长什么样子和它们是怎么存放在系统空间的。dentry结构主要包含了文件名,文件的inode号,指向父目录dentry结构的指针和其他一些与本次讨论无关的指针,这里关键是那个指向父目录的指针;系统中所有的dentry 结构都是按杂凑值存放在杂凑表中的,这里的杂凑算法很重要,它是取文件名和文件的父目录dentry结构的地址一起杂凑运算出杂凑值的。现在我们假设有两个目录 /a和/b,其中/b是我们通过ln -d命令建立起来的对/a的硬连接。这个时候内核空间中就会存在一个/a的dentry结构和一个/b的dentry结构,由上面的知识可知,/a和/b 目录下面的每一个文件或目录都各自有对应的dentry结构(因为虽然/a目录下面的文件名没有改变,但是因为dentry结构有指向父目录dentry 的指针和计算杂凑值时考虑了父目录dentry结构的地址,这个时候dentry结构就分身乏术了),而且这种继承还会影响到所有子目录下面的文件,这样下来就会浪费很多系统空间了,特别是如果被硬连接的目录中存在大量文件和子目录的时候就更加明显了。这也许是第二个原因。
9月29日

Linux的登陆脚本

看一篇debian的学习笔记里面说,.bash_profile是bash全局设置文件,而.bashrc 是当一个bash shell调用另一个bash shell时候读取的设置。我在配置debian的时候,参照网上的一个做法,将/etc/.bash_profile里面内容复制到/root /.bashrc内,并将下列反注释掉

if [ -f /etc/bash_completion ]; then

. /etc/bash_completion
fi

使root帐户具有table补全的能力。

那么,我的问题就在这里,我登录linux时候,直接登录的root帐户,并没有调用其他的shell阿,那么怎么需要将这些复制到.bashrc 中,并反注释掉这些,才能具有补全作用?如果我直接将.bash_profile中的这几句反注释掉,是不是root帐户也具有了补全的能力了?我安装系统时候,新建了一个用户,这个用户并不需要这一步设置,就直接具有补全作用了,这个帐户下的.bashrc有上面的内容了。这是为什么?

1. 首先要分清login shell和non-login shell, login shell是用户登录的时候启动的带身份验证的shell, /etc/passwd中可以看到,username对应的shell name,常见的是bin/bash. 当login shell启动后,会读入两个文件,/etc/profile 和用户根目录下的.bash_profile(如果没有,会再执行~/.bash_login, ~/.profile).

2. shell还分交互式shell和非交互式shell, 显然login shell也是一种交互式的shell。对于non-login的交互式shell, 启动时会执行~/.bashrc,而~/.bashrc中又会去执行/etc/bashrc. 对于login shell,为了更一致一些所以会在~/.bash_profile中执行~/.bashrc,所以对.bashrc的修改能影响所有的交互式 shell。

3. 新添加一个用户时,会添加一个记录到/etc/passwd,创建用户的home目录,将/etc/skel目录下的内容,拷贝到home目录下,skel中包含了用户home目录的基本文件和目录结构,包括.bashrc.(当然这些都是可以用户自定义的,如useradd -k -m 什么的)。

4 .bashrc确实是为non-login 交互式shell准备的。login shell并不直接读取,但是在.bahs_profile中会执行。
5 .对于login shell改bash_profile当然也可以。所以是修改.bash_profile还是.bashrc,要看具体的情况。
6 .至于新建用户的问题,看看/etc/skel。

当然最有效的就是把.bash_profile改了,登录看看,往/etc/skel里添加几个文件,改改.bashrc,再创建一个新用户看看。鉴于linux的多样性,实践+理解才是王道。

9月26日

automake & autoconf教程

http://www.amath.washington.edu/~lf/tutorials/autoconf/index.html

XML的本质

(这里的XML不仅仅指XML脚本语言,还包括XML的一系列技术,包括DTD,XSLT,XML SCHEMA,XPATH,DOM,SAX等等)

XML的本质是什么?这个问题对于很多XML的初学者来说都不容易回答。因为XML涉及的方面太多,有人是为了写出更漂亮的网页才从HTML进一步学到XML;有人是为了学JAVA才来了解XML;有人是从数据库到XML;有人是从UML到XML;当然还有一些人是从SOAP或者其他网络协议而了解到XML。那么到底如何解释XML的本质呢?

我认为XML的本质是数据,XML文档实际上是对数据的格式化存储,而XML的一系列技术都是围绕着数据来发展的。例如DTD、Schema是对数据格式的定义和检验;XSLT是对数据的转换;DOM、SAX是对数据的提取和操作。

既然XML只是数据,而且是用文本形式存储的数据,那么为什么不更简单的用普通文本来存储数据呢?早期的一些程序员确实是这么做的,但是这么做的缺点是对于每一组数据,都需要专用的数据格式定义、检验、转换和操作的程序。如果使用XML来存储数据,由于XML的一系列技术已经对以上的问题提供了工具,我们只需要使用那些技术即可快捷的达到自己的目的。有人可能会说,使用数据库不是更方便么?它也提供了以上的功能。确实如此,但是并不是每个地方都适用数据库的,如果说数据库是大而全的数据解决方案的话,XML可以用“举重若轻,大象无形”来形容,这一点后面再讨论。

XML的本质决定了它在网页制作方面比HTML更具有优越性。传统的网页包括HTML+CSS,在这种模式中,数据和数据的显示特性都包含在HTML中,CSS只是对显示特性的一种补充;而XML网页包括XML+XML Schema+XSL,其中XML存储数据,XML Schema定义了数据的存储格式,XSL定义了数据的显示特性(其实它定义了如何将XML转换为HTML,实际上就是定义了数据的显示特性)。使用XML制作的网页将数据、数据格式和显示特性清晰的分为三个部分,在添加或者修改网页的时候可以单独的修改每个部分,从而得到更好的维护性和更高的制作效率。当然动态网页可以由Database+脚本语言(JSP、ASP、PHP)+HTML+CSS组成;同样基于XML的动态网页可以由Database+中间程序(提取数据库内容形成XML文档)+XML+XML Schema+XSL组成。基于XML的解决方案同样保持了层次清晰的优点。

对于XML和数据库的比较,我的上一篇文章中有过讨论()。从本质上来说,XML和数据的本质差不多,都是围绕着数据来提供一系列的解决方案,但是它们之间存在几个显著的不同:1.XML是轻量级的数据解决方案,容易学习,可以用文本编辑器进行编辑,一般的浏览器都支持XSLT,适用于数据量小的各种环境;2.XML是完全平台无关的,不需要依赖于特定的操作系统、浏览器或者编程语言,而数据库不是完全平台无关的;3.XML是基于文本的,适合于网络传输,你不能指望每个EJB的配置文档都用数据库来表示吧;4.XML和数据库是可以互相结合和转换的。

对数据的不同理解可以将XML应用到不同的方面。你可以这样理解:XML是数据库中的数据;Schema是数据库的表;XSL是显示数据的程序;也可以这么理解:XML是网页素材;Schema是素材的数据结构;XSL是素材的显示特性。同样,在软件建模方面,也可以用XML来替代UML。这是基于这么一种理解:Schema代表类图,它如同UML一样存储了类的结构特性;XML代表对象,它存储了类的实例化对象的属性数据;而XSL是对类图的转换,即MDA(Model Driven Architecture,模型驱动架构)中的提到的模型转换。在UML中没有模型转换技术,但是一些UML工具提供了代码生成的功能(例如RationalRose),这中功能可以理解为模型转换的一个特例。因此有人提出了用XSLT做代码生成的建议,事实上这种代码生成技术已经比较成熟。由于XML Schema并不是天生就用来刻划类图的,所以它在类的继承等方面存在一些不足之处,为了修正这些不足,OMG(Object Manage Group,对象管理组)组织提出了XMI(XML Metadata Interchange,XML元数据交换)标准,用来补充XML Schema在软件建模方面的不足。现在XMI已经变成了各种软件建模工具的通用存储方式,可以将不同建模工具建立的模型互相转换。

总的来说,XML是一种基于文本的、格式化的数据存储技术,它包括一系列的数据解决方案,它们是轻量级的、易于学习的、平台无关的数据解决方案。弄清楚了这个概念再去学习XML,也许更有帮助。

C++的XML编程经验――LIBXML2库使用指南

C++的XML编程经验――LIBXML2库使用指南

写这篇文章的原因有如下几点:1)C++标准库中没有操作XML的方法,用C++操作XML文件必须熟悉一种函数库,LIBXML2是其中一种很优秀的XML库,而且它同时支持多种编程语言;2)LIBXML2库的Tutorial写得不太好,尤其是编码转换的部分,不适用于中文编码的转换;3)网上的大多数关于Libxml2的介绍仅仅是翻译了自带的资料,没有详细介绍如何在windows平台下进行编程,更很少提到如何解决中文问题。

基于以上几点原因,决定写一个在Windows平台下,使用C/C++语言,应用LibXml2库来进行xml文档操作,同时使用ICONV库进行中文编码转换的文档。其中还涉及了Makefile、XPATH等相关内容。本文中所有的源代码在http://www.blogjava.net/Files/wxb_nudt/xml_src.rar

1. 下载与安装LIBXML2和ICONV

Libxml2是一个C语言的XML程序库,可以简单方便的提供对XML文档的各种操作,并且支持XPATH查询,以及部分的支持XSLT转换等功能。Libxml2的下载地址是http://xmlsoft.org/,完全版的库是开源的,并且带有例子程序和说明文档。最好将这个库先下载下来,因为这样可以查看其中的文档和例子。

windows版本的的下载地址是http://www.zlatkovic.com/libxml.en.html;这个版本只提供了头文件、库文件和dll,不包含源代码、例子程序和文档。在文本中,只需要下载libxml2库、iconv库和zlib库就行了(注意,libxml2库依赖iconv和zlib库,本文中重点关注libxml2和iconv,zlib不介绍),我使用的版本是libxml2-2.6.30.win32.zip、zlib-1.2.3.win32.zip和iconv-1.9.2.win32.zip。

在编程的时候,我们使用windows版本的libxml2、zlib和iconv,将其解压缩到指定文件夹,例如D:"libxml2-2.6.30.win32,D:"zlib-1.2.3.win32以及D:"iconv-1.9.2.win32。事实上,我们知道在windows下面使用头文件、库文件和dll是不需要安装的,它又没有使用任何需要注册的组件或者数据库,只需要告诉编译器和链接器这些资源的位置就可以了。

注意:要在path变量中加上D:"iconv-1.9.2.win32"bin;D:"zlib-1.2.3.win32"bin;D:"libxml2-2.6.30.win32"bin这三个地址,否则在执行的时候就找不到。或者使用更简单的方法,把其中的三个dll到拷贝到system32目录中。

有两种方法来编译链接基于libxml2的程序,第一种是在VC环境中设置lib和include路径,并在link设置中添加libxml2.lib和iconv.lib;第二种是用编译器选项告诉编译器cl.exe头文件的位置,并用链接器选项告诉链接器link.exe库文件的位置,同时在windows环境变量path中添加libxml2中bin文件夹的位置,以便于程序运行时可以找到dll(也可以将dll拷贝到system32目录下)。显然我选择了第二种,那么编译链接一个名为CreateXmlFile.cpp源文件的命令如下:

cl /c /I D:"iconv-1.9.2.win32"include /I D:"libxml2-2.6.30.win32"include CreateXmlFile.cpp

link /libpath:D:"iconv-1.9.2.win32"lib /libpath:D:"libxml2-2.6.30.win32"lib CreateXmlFile.obj iconv.lib libxml2.lib

显然这样很费时,那么再不用makefile就显得矫情了,于是,一个典型的使用nmake.exe(VC自带的makefile工具)的文件如下:MAKEFILE

#

# 本目录下所有源代码的makefile,使用方法是nmake TARGET_NAME=源代码文件名字(不加后缀)

# 例如 nmake TARGET_NAME=CreateXmlFile

# Author: Wang Xuebin

#

# Flags - 编译debug版本

#

#指定要使用的库的路径,需要用户修改的变量一般放在makefile文件的最上面

LIBXML2_HOME = D:"libxml2-2.6.30.win32

ICONV_HOME = D:"iconv-1.9.2.win32

#指定编译器选项,/c表明cl命令只编译不链接;/MTd表明使用多线程debug库;/Zi表明产生完整的调试信息;

#/Od表明关闭编译优化;/D _DEBUG表明定义一个名为_DEBUG的宏

CPP_FLAGS=/c /MTd /Zi /Od /D _DEBUG

#链接选项,/DEBUG表明创建Debug信息

EXE_LINK_FLAGS=/DEBUG

#指定链接的库

LIBS=iconv.lib libxml2.lib

#指定编译路径选项,链接路径选项

INCLUDE_FLAGS= /I $(LIBXML2_HOME)"include /I $(ICONV_HOME)"include

LIB_PATH_FLAGS = /libpath:$(ICONV_HOME)"lib /libpath:$(LIBXML2_HOME)"lib

#################################################

#

# Targets 目标

#

$(TARGET_NAME) : $(TARGET_NAME).exe

clean : $(TARGET_NAME).exe

$(TARGET_NAME).obj : $(TARGET_NAME).cpp

    cl $(CPP_FLAGS) $(INCLUDE_FLAGS) $(TARGET_NAME).cpp

$(TARGET_NAME).exe : $(TARGET_NAME).obj

link $(EXE_LINK_FLAGS) $(LIB_PATH_FLAGS) $(TARGET_NAME).obj $(LIBS)

clean : $(TARGET_NAME).exe

del $(TARGET_NAME).exe

del $(TARGET_NAME).obj

del $(TARGET_NAME).ilk

del $(TARGET_NAME).pdb

本文不准备介绍makefile的写法,但后续例子程序的编译链接依葫芦画瓢都没有问题,执行编译链接的命令如下:

nmake TARGET_NAME=CreateXmlFile

执行清理的命令如下:

nmake TARGET_NAME=CreateXmlFile clean

2. Libxml2中的数据类型和函数

一个函数库中可能有几百种数据类型以及几千个函数,但是记住大师的话,90%的功能都是由30%的内容提供的。对于libxml2,我认为搞懂以下的数据类型和函数就足够了。

2.1 内部字符类型xmlChar

xmlChar是Libxml2中的字符类型,库中所有字符、字符串都是基于这个数据类型。事实上它的定义是:xmlstring.h

typedef unsigned char xmlChar;

使用unsigned char作为内部字符格式是考虑到它能很好适应UTF-8编码,而UTF-8编码正是libxml2的内部编码,其它格式的编码要转换为这个编码才能在libxml2中使用。

还经常可以看到使用xmlChar*作为字符串类型,很多函数会返回一个动态分配内存的xmlChar*变量,使用这样的函数时记得要手动删除内存。

2.2 xmlChar相关函数

如同标准c中的char类型一样,xmlChar也有动态内存分配、字符串操作等相关函数。例如xmlMalloc是动态分配内存的函数;xmlFree是配套的释放内存函数;xmlStrcmp是字符串比较函数等等。

基本上xmlChar字符串相关函数都在xmlstring.h中定义;而动态内存分配函数在xmlmemory.h中定义。

2.3 xmlChar*与其它类型之间的转换

另外要注意,因为总是要在xmlChar*和char*之间进行类型转换,所以定义了一个宏BAD_CAST,其定义如下:xmlstring.h

#define BAD_CAST (xmlChar *)

原则上来说,unsigned char和char之间进行强制类型转换是没有问题的。

2.4 文档类型xmlDoc、指针xmlDocPtr

xmlDoc是一个struct,保存了一个xml的相关信息,例如文件名、文档类型、子节点等等;xmlDocPtr等于xmlDoc*,它搞成这个样子总让人以为是智能指针,其实不是,要手动删除的。

xmlNewDoc函数创建一个新的文档指针。

xmlParseFile函数以默认方式读入一个UTF-8格式的文档,并返回文档指针。

xmlReadFile函数读入一个带有某种编码的xml文档,并返回文档指针;细节见libxml2参考手册。

xmlFreeDoc释放文档指针。特别注意,当你调用xmlFreeDoc时,该文档所有包含的节点内存都被释放,所以一般来说不需要手动调用xmlFreeNode或者xmlFreeNodeList来释放动态分配的节点内存,除非你把该节点从文档中移除了。一般来说,一个文档中所有节点都应该动态分配,然后加入文档,最后调用xmlFreeDoc一次释放所有节点申请的动态内存,这也是为什么我们很少看见xmlNodeFree的原因。

xmlSaveFile将文档以默认方式存入一个文件。

xmlSaveFormatFileEnc可将文档以某种编码/格式存入一个文件中。

2.5 节点类型xmlNode、指针xmlNodePtr

节点应该是xml中最重要的元素了,xmlNode代表了xml文档中的一个节点,实现为一个struct,内容很丰富:tree.h

typedef struct _xmlNode xmlNode;

typedef xmlNode *xmlNodePtr;

struct _xmlNode {

    void           *_private;/* application data */

    xmlElementType   type;   /* type number, must be second ! */

    const xmlChar   *name;      /* the name of the node, or the entity */

    struct _xmlNode *children; /* parent->childs link */

    struct _xmlNode *last;   /* last child link */

    struct _xmlNode *parent;/* child->parent link */

    struct _xmlNode *next;   /* next sibling link */

    struct _xmlNode *prev;   /* previous sibling link */

    struct _xmlDoc *doc;/* the containing document */

    /* End of common part */

    xmlNs           *ns;        /* pointer to the associated namespace */

    xmlChar         *content;   /* the content */

    struct _xmlAttr *properties;/* properties list */

    xmlNs           *nsDef;     /* namespace definitions on this node */

    void            *psvi;/* for type/PSVI informations */

    unsigned short   line;   /* line number */

    unsigned short   extra; /* extra data for XPath/XSLT */

};

可以看到,节点之间是以链表和树两种方式同时组织起来的,next和prev指针可以组成链表,而parent和children可以组织为树。同时还有以下重要元素:

l 节点中的文字内容:content;

l 节点所属文档:doc;

l 节点名字:name;

l 节点的namespace:ns;

l 节点属性列表:properties;

Xml文档的操作其根本原理就是在节点之间移动、查询节点的各项信息,并进行增加、删除、修改的操作。

xmlDocSetRootElement函数可以将一个节点设置为某个文档的根节点,这是将文档与节点连接起来的重要手段,当有了根结点以后,所有子节点就可以依次连接上根节点,从而组织成为一个xml树。

2.6 节点集合类型xmlNodeSet、指针xmlNodeSetPtr

节点集合代表一个由节点组成的变量,节点集合只作为Xpath的查询结果而出现(XPATH的介绍见后面),因此被定义在xpath.h中,其定义如下:

/*

* A node-set (an unordered collection of nodes without duplicates).

*/

typedef struct _xmlNodeSet xmlNodeSet;

typedef xmlNodeSet *xmlNodeSetPtr;

struct _xmlNodeSet {

    int nodeNr;          /* number of nodes in the set */

    int nodeMax;      /* size of the array as allocated */

    xmlNodePtr *nodeTab;/* array of nodes in no particular order */

    /* @@ with_ns to check wether namespace nodes should be looked at @@ */

};

可以看出,节点集合有三个成员,分别是节点集合的节点数、最大可容纳的节点数,以及节点数组头指针。对节点集合中各个节点的访问方式很简单,如下:

xmlNodeSetPtr nodeset = XPATH查询结果;

for (int i = 0; i < nodeset->nodeNr; i++)

{

nodeset->nodeTab[i];

}

注意,libxml2是一个c函数库,因此其函数和数据类型都使用c语言的方式来处理。如果是c++,我想我宁愿用STL中的vector来表示一个节点集合更好,而且没有内存泄漏或者溢出的担忧。

3. 简单xml操作例子

了解以上基本知识之后,就可以进行一些简单的xml操作了。当然,还没有涉及到内码转换(使得xml中可以处理中文)、xpath等较复杂的操作。

3.1 创建xml文档

有了上面的基础,创建一个xml文档显得非常简单,其流程如下:

l 用xmlNewDoc函数创建一个文档指针doc;

l 用xmlNewNode函数创建一个节点指针root_node;

l 用xmlDocSetRootElement将root_node设置为doc的根结点;

l 给root_node添加一系列的子节点,并设置子节点的内容和属性;

l 用xmlSaveFile将xml文档存入文件;

l 用xmlFreeDoc函数关闭文档指针,并清除本文档中所有节点动态申请的内存。

注意,有多种方式可以添加子节点:第一是用xmlNewTextChild直接添加一个文本子节点;第二是先创建新节点,然后用xmlAddChild将新节点加入上层节点。

源代码文件是CreateXmlFile.cpp,如下:

/********************************************************************

    created:   2007/11/09

    created:   9:11:2007   15:34

    filename: CreateXmlFile.cpp

    author:       Wang xuebin

    depend:       libxml2.lib

    build:     nmake TARGET_NAME=CreateXmlFile

    purpose:   创建一个xml文件

*********************************************************************/

#include <stdio.h>

#include <libxml/parser.h>

#include <libxml/tree.h>

#include <iostream.h>

int main()

{

    //定义文档和节点指针

    xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");

    xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST"root");

    //设置根节点

    xmlDocSetRootElement(doc,root_node);

    //在根节点中直接创建节点

    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");

    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");

    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");

    //创建一个节点,设置其内容和属性,然后加入根结点

    xmlNodePtr node = xmlNewNode(NULL,BAD_CAST"node2");

    xmlNodePtr content = xmlNewText(BAD_CAST"NODE CONTENT");

    xmlAddChild(root_node,node);

    xmlAddChild(node,content);

    xmlNewProp(node,BAD_CAST"attribute",BAD_CAST "yes");

    //创建一个儿子和孙子节点

    node = xmlNewNode(NULL, BAD_CAST "son");

    xmlAddChild(root_node,node);

    xmlNodePtr grandson = xmlNewNode(NULL, BAD_CAST "grandson");

    xmlAddChild(node,grandson);

    xmlAddChild(grandson, xmlNewText(BAD_CAST "This is a grandson node"));

    //存储xml文档

    int nRel = xmlSaveFile("CreatedXml.xml",doc);

    if (nRel != -1)

    {

       cout<<"一个xml文档被创建,写入"<<nRel<<"个字节"<<endl;

    }

    //释放文档内节点动态申请的内存

    xmlFreeDoc(doc);

    return 1;

}

编译链接命令如下:

nmake TARGET_NAME=CreateXmlFile

然后执行可执行文件CreateXmlFile.exe,会生成一个xml文件CreatedXml.xml,打开后如下所示:

<?xml version="1.0"?>

<root>

<newNode1>newNode1 content</newNode1>

<newNode2>newNode2 content</newNode2>

<newNode3>newNode3 content</newNode3>

<node2 attribute="yes">NODE CONTENT</node2>

<son>

<grandson>This is a grandson node</grandson>

</son>

</root>

最好使用类似XMLSPY这样的工具打开,因为这些工具可以自动整理xml文件的栅格,否则很有可能是没有任何换行的一个xml文件,可读性较差。

3.2 解析xml文档

解析一个xml文档,从中取出想要的信息,例如节点中包含的文字,或者某个节点的属性,其流程如下:

l 用xmlReadFile函数读出一个文档指针doc;

l 用xmlDocGetRootElement函数得到根节点curNode;

l curNode->xmlChildrenNode就是根节点的子节点集合;

l 轮询子节点集合,找到所需的节点,用xmlNodeGetContent取出其内容;

l 用xmlHasProp查找含有某个属性的节点;

l 取出该节点的属性集合,用xmlGetProp取出其属性值;

l 用xmlFreeDoc函数关闭文档指针,并清除本文档中所有节点动态申请的内存。

注意:节点列表的指针依然是xmlNodePtr,属性列表的指针也是xmlAttrPtr,并没有xmlNodeList或者xmlAttrList这样的类型。看作列表的时候使用它们的next和prev链表指针来进行轮询。只有在Xpath中有xmlNodeSet这种类型,其使用方法前面已经介绍了。

源代码如下:ParseXmlFile.cpp

/********************************************************************

    created:   2007/11/15

    created:   15:11:2007   11:47

    filename: ParseXmlFile.cpp

    author:       Wang xuebin

    depend:       libxml2.lib

    build:     nmake TARGET_NAME=ParseXmlFile

    purpose:   解析xml文件

*********************************************************************/

#include <libxml/parser.h>

#include <iostream.h>

int main(int argc, char* argv[])

{

    xmlDocPtr doc;           //定义解析文档指针

    xmlNodePtr curNode;      //定义结点指针(你需要它为了在各个结点间移动)

    xmlChar *szKey;          //临时字符串变量

    char *szDocName;

    if (argc <= 1) 

    {

       printf("Usage: %s docname"n", argv[0]);

       return(0);

    }

    szDocName = argv[1];

    doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER); //解析文件

    //检查解析文档是否成功,如果不成功,libxml将指一个注册的错误并停止。

    //一个常见错误是不适当的编码。XML标准文档除了用UTF-8或UTF-16外还可用其它编码保存。

    //如果文档是这样,libxml将自动地为你转换到UTF-8。更多关于XML编码信息包含在XML标准中.

    if (NULL == doc)

    {  

       fprintf(stderr,"Document not parsed successfully. "n");    

       return -1;

    }

    curNode = xmlDocGetRootElement(doc); //确定文档根元素

    /*检查确认当前文档中包含内容*/

    if (NULL == curNode)

    {

       fprintf(stderr,"empty document"n");

       xmlFreeDoc(doc);

       return -1;

    }

    /*在这个例子中,我们需要确认文档是正确的类型。“root”是在这个示例中使用文档的根类型。*/

    if (xmlStrcmp(curNode->name, BAD_CAST "root"))

    {

       fprintf(stderr,"document of the wrong type, root node != root");

       xmlFreeDoc(doc);

       return -1;

    }

    curNode = curNode->xmlChildrenNode;

    xmlNodePtr propNodePtr = curNode;

    while(curNode != NULL)

    {

       //取出节点中的内容

       if ((!xmlStrcmp(curNode->name, (const xmlChar *)"newNode1")))

       {

           szKey = xmlNodeGetContent(curNode);

           printf("newNode1: %s"n", szKey);

           xmlFree(szKey);

       }

       //查找带有属性attribute的节点

       if (xmlHasProp(curNode,BAD_CAST "attribute"))

       {

           propNodePtr = curNode;

       }

       curNode = curNode->next;

    }

    //查找属性

    xmlAttrPtr attrPtr = propNodePtr->properties;

    while (attrPtr != NULL)

    {

       if (!xmlStrcmp(attrPtr->name, BAD_CAST "attribute"))

       {

           xmlChar* szAttr = xmlGetProp(propNodePtr,BAD_CAST "attribute");

           cout<<"get attribute = "<<szAttr<<endl;

           xmlFree(szAttr);

       }

       attrPtr = attrPtr->next;

    }

    xmlFreeDoc(doc);

    return 0;

}

编译链接命令如下:

nmake TARGET_NAME=ParseXmlFile

执行命令如下,使用第一次创建的xml文件作为输入:

ParseXmlFile.exe CreatedXml.xml

观察源代码可发现,所有以查询方式得到的xmlChar*字符串都必须使用xmlFree函数手动释放。否则会造成内存泄漏。

3.3 修改xml文档

有了上面的基础,修改xml文档的内容就很简单了。首先打开一个已经存在的xml文档,顺着根结点找到需要添加、删除、修改的地方,调用相应的xml函数对节点进行增、删、改操作。源代码见ChangeXmlFile,编译链接方法如上。执行下面的命令:

ChangeXmlFile.exe CreatedXml.xml

可以得到一个修改后的xml文档ChangedXml.xml,如下:

<?xml version="1.0"?>

<root>

<newNode2>content changed</newNode2>

<newNode3 newAttr="YES">newNode3 content</newNode3>

<node2 attribute="no">NODE CONTENT</node2>

<son>

<grandson>This is a grandson node</grandson>

<newGrandSon>new content</newGrandSon>

</son>

</root>

需要注意的是,并没有xmlDelNode或者xmlRemoveNode函数,我们删除节点使用的是以下一段代码:

       if (!xmlStrcmp(curNode->name, BAD_CAST "newNode1"))

       {

           xmlNodePtr tempNode;

           tempNode = curNode->next;

           xmlUnlinkNode(curNode);

           xmlFreeNode(curNode);

           curNode = tempNode;

           continue;

       }

即将当前节点从文档中断链(unlink),这样本文档就不会再包含这个子节点。这样做需要使用一个临时变量来存储断链节点的后续节点,并记得要手动删除断链节点的内存。

3.4 使用XPATH查找xml文档

简而言之,XPATH之于xml,好比SQL之于关系数据库。要在一个复杂的xml文档中查找所需的信息,XPATH简直是必不可少的工具。XPATH语法简单易学,并且有一个很好的官方教程,见http://www.zvon.org/xxl/XPathTutorial/Output_chi/introduction.html。这个站点的XML各种教程齐全,并且有包括中文在内的各国语言版本,真是让我喜欢到非常!

使用XPATH之前,必须首先熟悉几个数据类型和函数,它们是使用XPATH的前提。在libxml2中使用Xpath是非常简单的,其流程如下:

l 定义一个XPATH上下文指针xmlXPathContextPtr context,并且使用xmlXPathNewContext函数来初始化这个指针;

l 定义一个XPATH对象指针xmlXPathObjectPtr result,并且使用xmlXPathEvalExpression函数来计算Xpath表达式,得到查询结果,将结果存入对象指针中;

l 使用result->nodesetval得到节点集合指针,其中包含了所有符合Xpath查询结果的节点;

l 使用xmlXPathFreeContext释放上下文指针;

l 使用xmlXPathFreeObject释放Xpath对象指针;

具体的使用方法可以看XpathForXmlFile.cpp的这一段代码,其功能是查找符合某个Xpath语句的对象指针:

xmlXPathObjectPtr getNodeSet(xmlDocPtr doc, const xmlChar *szXpath)

{

    xmlXPathContextPtr context;    //XPATH上下文指针

    xmlXPathObjectPtr result;       //XPATH对象指针,用来存储查询结果

    context = xmlXPathNewContext(doc);     //创建一个XPath上下文指针

    if (context == NULL)

    {  

       printf("context is NULL"n");

       return NULL;

    }

    result = xmlXPathEvalExpression(szXpath, context); //查询XPath表达式,得到一个查询结果

    xmlXPathFreeContext(context);             //释放上下文指针

    if (result == NULL)

    {

       printf("xmlXPathEvalExpression return NULL"n");

       return NULL; 

    }

    if (xmlXPathNodeSetIsEmpty(result->nodesetval))   //检查查询结果是否为空

    {

       xmlXPathFreeObject(result);

       printf("nodeset is empty"n");

       return NULL;

    }

    return result;   

}

一个完整的使用Xpath的例子在代码XpathForXmlFile.cpp中,它查找一个xml文件中符合"/root/node2[@attribute='yes']"语句的结果,并且将找到的节点的属性和内容打印出来。编译链接命令如下:

nmake TARGET_NAME=XpathForXmlFile

执行方式如下:

XpathForXmlFile.exe CreatedXml.xml

观察结果可以看出找到了一个节点,即root下面node2节点,它的attribute属性值正好等于yes。更多关于Xpath的内容可以参考XPATH官方手册。只有掌握了XPATH,才掌握了使用大型XML文件的方法,否则每寻找一个节点都要从根节点找起,会把人累死。

4. 用ICONV解决XML中的中文问题

Libxml2中默认的内码是UTF-8,所有使用libxml2进行处理的xml文件,必须首先显式或者默认的转换为UTF-8编码才能被处理。

要在xml中使用中文,就必须能够在UTF-8和GB2312内码(较常用的一种简体中文编码)之间进行转换。Libxml2提供了默认的内码转换机制,并且在libxml2的Tutorial中有一个例子,事实证明这个例子并不适合用来转换中文。

所以需要我们显式的使用ICONV来进行内码转换,libxml2本身也是使用ICONV进行转换的。ICONV是一个专门用来进行编码转换的库,基本上支持目前所有常用的编码。它是glibc库的一个部分,常常被用于UNIX系统中。当然,在windows下面使用也没有任何问题。前面已经提到了ICONV的安装和使用方法,这里主要讲一下编程相关问题。

本节其实和xml以及libxml2没有太大关系,你可以把它简单看作是一个编码转换方面的专题。我们仅仅需要学会使用两个函数就可以了,即从UTF-8转换到GB2312的函数u2g,以及反向转换的函数g2u,源代码在wxb_codeConv.c中:

/********************************************************************

    created:   2007/11/15

    created:   15:11:2007   10:30

    filename: wxb_codeConv.c

    author:       Wang xuebin

    depend:       iconv.lib

    build:     不需要build,被包含到其它源代码中

    purpose:   提供从UTF-8到GB2312的内码转换,以及反向的转换

*********************************************************************/

#include "iconv.h"

#include <string.h>

//代码转换:从一种编码转为另一种编码

int code_convert(char* from_charset, char* to_charset, char* inbuf,

               int inlen, char* outbuf, int outlen)

{

    iconv_t cd;

    char** pin = &inbuf;  

    char** pout = &outbuf;

    cd = iconv_open(to_charset,from_charset);  

    if(cd == 0)

       return -1;

    memset(outbuf,0,outlen);  

    if(iconv(cd,(const char**)pin,(unsigned int *)&inlen,pout,(unsigned int*)&outlen)

       == -1)

       return -1;  

    iconv_close(cd);

    return 0;  

}

//UNICODE码转为GB2312码  

//成功则返回一个动态分配的char*变量,需要在使用完毕后手动free,失败返回NULL

char* u2g(char *inbuf)  

{

    int nOutLen = 2 * strlen(inbuf) - 1;

    char* szOut = (char*)malloc(nOutLen);

    if (-1 == code_convert("utf-8","gb2312",inbuf,strlen(inbuf),szOut,nOutLen))

    {

       free(szOut);

       szOut = NULL;

    }

    return szOut;

}  

//GB2312码转为UNICODE码

//成功则返回一个动态分配的char*变量,需要在使用完毕后手动free,失败返回NULL

char* g2u(char *inbuf)  

{

    int nOutLen = 2 * strlen(inbuf) - 1;

    char* szOut = (char*)malloc(nOutLen);

    if (-1 == code_convert("gb2312","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))

    {

       free(szOut);

       szOut = NULL;

    }

    return szOut;

}  

使用的时候将这个c文件include到其它源文件中。include一个c文件并不奇怪,在c语言的年代我们常常这么干,唯一的害处的编译链接出来的可执行程序体积变大了。当然这时因为我们这段代码很小的原因,再大一点我就要用dll了。

从UTF-8到GB2312的一个典型使用流程如下:

l 得到一个UTF-8的字符串szSrc;

l 定义一个char*的字符指针szDes,并不需要给他动态审判内存;

l szDes = u2g(szSrc),这样就可以得到转换后的GB2312编码的字符串;

l 使用完这个字符串后使用free(szDes)来释放内存。

本文并不准备讲述iconv中的函数细节,因为那几个函数以及数据类型都非常简单,我们还是重点看一下如何在libxml2中使用编码转换来处理带有中文的xml文件。下面是使用以上方法来创建一个带有中文的XML文件的例子程序CreateXmlFile_cn.cpp,源代码如下:

/********************************************************************

    created:   2007/11/17

    created:   9:11:2007   15:34

    filename: CreateXmlFile.cpp

    author:       Wang xuebin

    depend:       libxml2.lib iconv.lib

    build:     nmake TARGET_NAME=CreateXmlFile_cn

    purpose:   创建一个xml文件,其中包含中文

*********************************************************************/

#include <stdio.h>

#include <libxml/parser.h>

#include <libxml/tree.h>

#include <iostream.h>

#include "wxb_codeConv.c" //自己写的编码转换函数

int main(int argc, char **argv)

{

    //定义文档和节点指针

    xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");

    xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST"root");

    //设置根节点

    xmlDocSetRootElement(doc,root_node);

    //一个中文字符串转换为UTF-8字符串,然后写入

    char* szOut = g2u("节点1的内容");

    //在根节点中直接创建节点

    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");

    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");

    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");

    xmlNewChild(root_node, NULL, BAD_CAST "node1",BAD_CAST szOut);

    free(szOut);

    //创建一个节点,设置其内容和属性,然后加入根结点

    xmlNodePtr node = xmlNewNode(NULL,BAD_CAST"node2");

    xmlNodePtr content = xmlNewText(BAD_CAST"NODE CONTENT");

    xmlAddChild(root_node,node);

    xmlAddChild(node,content);

    szOut = g2u("属性值");

    xmlNewProp(node,BAD_CAST"attribute",BAD_CAST szOut);

    free(szOut);

    //创建一个中文节点

    szOut = g2u("中文节点");

    xmlNewChild(root_node, NULL, BAD_CAST szOut,BAD_CAST "content of chinese node");

    free(szOut);

    //存储xml文档

    int nRel = xmlSaveFormatFileEnc("CreatedXml_cn.xml",doc,"GB2312",1);

    if (nRel != -1)

    {

       cout<<"一个xml文档被创建,写入"<<nRel<<"个字节"<<endl;

    }

    xmlFreeDoc(doc);

    return 1;

}

编译链接命令如下:

nmake TARGET_NAME=CreateXmlFile_cn

完成后执行CreateXmlFile_cn.exe可以生成一个xml文件CreatedXml_cn.xml,其内容如下:

<?xml version="1.0" encoding="GB2312"?>

<root>

<newNode1>newNode1 content</newNode1>

<newNode2>newNode2 content</newNode2>

<newNode3>newNode3 content</newNode3>

<node1>节点1的内容</node1>

<node2 attribute="属性值">NODE CONTENT</node2>

<中文节点>content of chinese node</中文节点>

</root>

观察可知,节点的名称、内容、属性都可以使用中文了。在解析、修改和查找XML文档时都可以使用上面的方法,只要记住,进入xml文档之前将中文编码转换为UTF-8编码;从XML中取出数据时,不管三七二十一都可以转换为GB2312再用,否则你很有可能见到传说中的乱码!

5. 用XML来做点什么

有了以上的基础,相信已经可以顺利的在c/c++程序中使用XML文档了。那么,我们到底要用XML来做什么呢?我随便说一说自己的想法:

第一,可以用来作为配置文件。例如很多组件就是用XML来做配置文件;当然,我们知道用INI做配置文件更简单,只要熟悉两个函数就可以了;不过,复杂一点的配置文件我还是建议采用XML;

第二,可以用来作为在程序之间传送数据的格式,这样的话最好给你的xml先定义一个XML Schema,这样的数据首先可以做一个良构校验,还可以来一个Schema校验,如此的话出错率会比没有格式的数据小得多。目前XML已经广泛作为网络之间的数据格式了;

第三,可以用来作为你自定义的数据存储格式,例如对象持久化之类的功能;

最后,可以用来显示你的技术很高深,本来你要存储一个1,结果你这样存储了:

<?xml version="1.0" encoding="GB2312"?>

<root>

<My_Program_Code content="1"></My_Program_Code>

</root>

然后再用libxml2取出来,最好还来几次编码转换,是不是让人觉得你很牛呢,哈哈!说笑了,千万不要这么做。

makefile笔记

    注:这里的makefile指的是gnu makefile,可能跟其他的makefile略有不同。若有不同,我尽量提及。而且这也不算是一篇教程,只是我在用make的时候记得一些笔记。推荐看<>。另外网上有一篇《跟我一起写makefile》也很好。
    makefile规则分为三部分:目标(target)、条件(prerequisite)、命令(commands)。
    target:prereq1...prereqn
       commans
1.自动变量
    $@:代表目标文件名
    $%:The filename element of an archive member specification.
    $<:条件列表中的第一个条件的文件名
    $?:条件列表中所有比目标新的那些条件的文件名,以空格分割
    $^:条件列表中所有条件的文件名,以空格分割。如果列表中有重复的条件,则会被删掉。
    $+:跟$^类似,区别在不会去掉重复的条件。
    $*:目标文件名的词干部分(去掉扩展名剩下的部分)
    自动变量只能用在规则的命令部分,因为这些变量是make匹配到规则的目标和条件后才设置值的。
    举个例子说明一下。假设某个工程有三个文件:cal.cpp,cal.h,test.cpp(下面再有说明时也以此为例)。makefile如下:
        OBJS=test.o cal.o cal.o
        TARGET=cal.exe
        all:$(TARGET)
        $(TARGET):$(OBJS)
            @echo $@
            @echo $<
            @echo $^
            @echo $?
            @echo $+
            @echo $%
            @echo $*
    输出为:
            cal.exe
            test.o
            test.o cal.o
            test.o cal.o
            test.o cal.o cal.o
            ECHO is off.
            ECHO is off.
至于最后两个为什么会这样输出我还不太清楚,有清楚地麻烦告诉我一下这两个怎么用。先谢谢了
2.模式规则
    模式规则也是规则,也要满足make的规则形式,分为目标、条件、命令三个部分。只是目标、条件中的文件名的词干部分用%代替了,这个%跟shell中的*类似,代表任意长度的字符串。还以上面说得工程为例,makefile如下:
        CPPFLAGS= -g
        CC=g++
        test:cal.o test.o
        cal.o:cal.h
    make的时候,输出如下内容:
        g++  -g  -c -o test.o test.cpp
        g++  -g  -c -o cal.o cal.cpp
        g++   test.o cal.o   -o test
    这个makefile之所以能够正确被处理,是因为make内建了一些规则。例如:
        %.o: %.c
            $(COMPILE.c) $(OUTPUT_OPTION) $<
        %.o: %.cpp
            $(COMPILE.cpp) $(OUTPUT_OPTION) $<
    以及
        %: %.o
            $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
    这些规则里面的$变量都是make的标准变量(还有上面的CPPFLAGS,CC也是。另外还有一些别的),这些标准变量有的有默认值(例如CC的默认值是cc),有的没有。make在处理makefile文件时,如果没有显式的规则,那么就会查找是否有隐式的可用规则,如果找到就会利用隐式规则来生成目标。
    2.1静态模式规则
       静态模式规则指的是类似下面的规则:
        $(OBJECTS): %.o: %c
            $(CC) -c $(CFLAGS) $< -o $@
       这跟上面的模式规则类似,不同在于将规则的适用范围限制在了$(OBJECTS)。也就是只针对这些目标来应用规则。
    2.2后缀规则
       后缀规则是指用一个或者两个后缀连接起来作为目标,同时省略掉条件部分。如下:
       .c.o:
           $(COMPILE.c) $(OUTPUT_OPTION) $<
       容易混淆的地方是条件后缀在前,目标后缀在后。
       这跟上面的规则:
           %.o: %.c
               $(COMPILE.c) $(OUTPUT_OPTION) $<
       功能是一样的,只是为了兼容一些老的make系统。
       需要注意的是,这里用到的后缀必须在已知后缀列表里面。有个专用的目标(target)——.SUFFIXES——用来设定后缀列表。例如:.SUFFIXES:.pdf .o .c 。而.SUFFIXES:(也就是后面列表为空)用来清空后缀列表。
3.自动依赖生成
    还没发现这个在实际应用中有多方便,有兴趣的可以看看我开始推荐的两个文档。

9月19日

开源GPL中触目惊心的学术腐败

开源GPL中触目惊心的学术腐败

关键字:开源GPL

少数教授有这个特点,指导自己的学生做出了什么学术成果,就要把自己的名字添在前面,然后一级一级都加上自己的名字。人们痛斥这是学术腐败。
不过这样的学术腐败并不是中国独有的。在国外也一样,而且有远比此更甚者。在众目睽睽光天化日之下明目张胆这样做。

芬兰的Linus开发出LINUX操作系统,而richard stallman竟仅仅因为LINUX采用了GPL协议就要让所有人把LINUX 叫成GNU/Linux,在richard stallman每次出去为他的GNU GPL传教时都要这么说一番,然后还要带上一顶圆形宽边帽子扮演耶稣头上的光环让人们向他顶礼膜拜,而后他的教徒们为之疯狂,都说应该把LINUX 叫成GNU/Linux——可是,这不公平!

下列文字选自方兴东《自由软件创世纪》,
“自由软件的内部纷争如今,随着Linux神话般的成功,自由软件逐渐步入主流。但是人们更愿意将这一故事称为Linux,而不是GUN/Linux;人们更自然地将主角交给LinusTorvalds,而不是RichardStallman;人们更愿称其为“开源(开放源代码)软件”,而不叫“自由软件”。
  Stallman十分恼火,“他们将两者混为一谈,却否定了前人的工作。将这项工作归于某个人的名下是不公平的。”Stallman承认 Torvalds的贡献很关键,是他完成了GUN/Linux的内核。但是Stallman估算,内核只占整个系统的3%,相比之下,GUN项目贡献了 30%的代码,其余67%的代码来源于其他方面。”

下列文字选自方兴东《软件业自由之神---Richard Stallman》
“Richard Stallman说,Linux并不能代表整个操作系统。Linux只是内核,整个系统还包含数以百计的软件工具和实用程序,大多是由GNU黑客们完成的。他认为,整个操作系统称为GNU/Linux比较合适。”

但是无论LINUS还是ERIC等都对此表示强烈不满,LINUS甚至评价richard stallman 的EMACS说:“EMACS IS EVIL"。

richard stallman仅仅因为“内核只占整个系统的3%,相比之下,GUN项目贡献了30%的代码,其余67%的代码来源于其他方面”就要把自己的GNU的名字放在LINUX的前面。稍有常识的程序员就知道这是非常不合理的,难道程序员的工作是用代码量来衡量的吗?绝不是!richard stallman为了沽名钓誉竟然故意混淆这么基本的概念。

还有一种说法说 LINUX是用richard stallman的GCC编译的,所以要叫GNU/LINUX,这简直可笑至极。大家知道我们中国的WPS是用MICROSOFT VC编译的,可是MICROSOFT并没找WPS说要让WPS叫MICROSOFT WPS吧,我们好多程序员都在用MICROSOFT VC编程序,从来没听说过谁的程序要在前面加上MICROSOFT的名字。

没有GCC编译器,LINUX内核源代码稍微改动一下在MICROSOFT VC/MASM底下编译也是照样可以的嘛。LINUX少了GNU的那些代码一样叫LINUX,但是少了LINUS的内核就不能称其为LINUX了。

但是richard stallman弃财求名,得到很大的名声,引起很多人的膜拜,LINUS的话反而没多少人听了。我想起我们中国一句古话说贪名者往往比贪财者更危险更有欺骗性,这真是太正确了。

Richard Stallman从来撒谎不眨眼,说什么70年代以前软件都是开源的,这是弥天大谎!比如IBM OS360与MULTRICS开源了吗?

Richard Stallman还欺骗公众,说做商业软件的公司把盗版者称为魔鬼,说“其实,这样的人才是魔鬼;而诱人当魔鬼的,则是卖高价软件的人”,后来把做商业软件的人竟然都称做魔鬼,说软件是不应该有版权的。其实有几家做商业软件的公司把盗版者称为魔鬼呢?反正我在我们中国还没听说过,人家只是简单的抗议盗版就是了。我们只听见了Richard Stallman 把做商业软件的叫成魔鬼。其实动辄说别人是魔鬼的才是真正的魔鬼。

而且按照耶稣的说法,Richard Stallman是不折不扣的魔鬼,圣经里不是说冒充耶稣的都是魔鬼吗?偏偏这Richard Stallman就喜欢冒充耶稣,这是他最大的喜好,不信吗?且看如下文字(来自Richard Stallman在北京关于自由软件的专题讲座):

“演讲即将结束时,Stallman兴奋的摆出了他经典的教主造型:身着金色边幅的长袍,头戴象征耶稣光环环绕的帽子(其实是一个放大的老式硬盘盘片)--他真的开始虔诚的普渡众生!”于是台下的“盛况”可想而知了。——你看这整个一个邪教教主的姿态嘛。

按耶稣的说法,Richard Stallman真是不折不扣的魔鬼,那么GPL确实是不折不扣的邪教!

我不反对开源,但是开源怎能是这样的开源?!
GPL要让程序员开放源代码,而且任何人只要使用了GPL的代码就必须把整个软件全部开源,GPL的这种传染性本质上是病毒是瘟疫。
而且特别这邪教教主竟把是否开源跟人的道德挂上勾,在其强势蛊惑人心的宣传下不少人普遍认为开源者才是道德高尚的,否则就是自私。其实在GPL协议下的开源才真正是道德的沦丧!

1。GPL协议严重侵犯了程序员的自由与权利,你自己辛辛苦苦写的软件,本来开不开源是你自己的自由,可是如果你参与了GPL却就完全没有这样的权利,必须被强迫开源,否则会遭到法律起诉。GPL根本不配叫自由软件,因为它首先剥夺了程序员的对源代码的自由!

2.软件是应该有版权的,因为程序员为软件付出了无数艰辛,凭什么就要剥夺程序员的权利呢?

3. 从令人尊敬的仁慈的亲爱的微软BILL GATES 的1976年“致电脑爱好者的一封公开信”开始,软件正式开始成为一种产业,在BILL GATES 亲手缔造的这个产业中,我们千千万万程序员过着非常舒服的日子。仅仅BILL GATES 的win+vs就养着一大批程序员,很多人就是靠这个吃饭的。BILL GATES 身为世界首富,既富又仁,还给慈善事业捐了很多的钱。其道德远远比richard stallman高尚!richard stallman往慈善事业里捐过一分钱吗?(也许倒也不是一分没捐过,因为这是许多美国人的习惯)。

4.当被问及GPL开放源代码后程序员的生活怎么办时,Richard Stallman 非常不负责的说就让他们去做软件售后服务去好了,TMD,要让我们程序员去当坐台的啊?扁他!

5.GPL对客户也是非常不负责,总是推卸责任,客户出了什么问题总要责任自负。而商业软件是非常为客户负责的。

6.开源就是大公无私,不开源就是自私吗?前几天在CSDN看到一则新闻说FIREFOX在征集捐款好为其开发者提供资金,因为许多开发者饭都吃不饱了生活都有问题。这些开发者对公众多么“无私”啊,可是他们为自己的家人负责吗?一点都不负责,这才是真正的道德的沦丧,哪有自己家吃不饱肚子却还打肿脸充胖子“大公无私”的?说白了是在GPL的蛊惑下,这些人把自己在开源社区的名看的比什么都重要,为了他们自己的名不顾家人,这才是最不道德的。GPL令许多人失去了社会与家庭的责任感。

相比之下我们中国的程序员就好多了,我们中国程序员很多生活也是挺拮据的,但是我们在努力想办法挣钱养家,这是我们对家庭对社会负责的表现。中国程序员参与GPL项目的少是中国人民的光荣!绝不是耻辱。相反那些老指责中国程序员不参与GPL开源的老外才是耻辱的。

绝不可以用开不开源来衡量道德。

7.表面上GPL要服务大众,其实GPL非常缺乏对弱势群体的照顾,一些人总拿国外少数GPL开源程序员也很富说事,但是别忘了那是特别个例,一般的程序员能行吗?缺乏对弱势群体照顾的社会方案不值得采取。

引子:我为什么要写这些文章呢,因为我最近遇到了一些事情……其实现在很多程序员都遇到过这样的事情,你辛辛苦苦做出来的程序,忽然有人要你开放源代码,你要是不开放就被说成是自私不道德。现在遍天下的GPL教徒奉RMS或LINUS为教主就专干这事,RMS公开宣扬程序员再辛辛苦苦做出来的程序都是不应该有源代码的,而且不许别人反驳,谁若反驳这些教徒们就一拥而上用恶毒的语言谩骂,RMS甚至公开谩骂做商业软件的人是魔鬼,任何人都不能对GPL有任何异议,更不能怀疑RMS,其他问题上也是一样……可是这公道吗?

近年来多起大学教授抄袭、剽窃、学术造假在我国媒体上报道,人们为之愤愤不平时,我却发现,原来我们中国教授的抄袭还很不够,比外国差远了。可是很多人却只知道批判中国的抄袭,甚至恶意辱骂中国人就只会抄袭,可是对外国人的抄袭却无视,甚至大加崇拜。(LINUX正在大规模的抄袭剽窃UNIX)

近年来无论中国出了什么样的科研成果,很多人首先想到的不是“这是我们中国的又一个光荣”,而是考虑是否又在造假。很多科研成果稍微带点“国际先进”的词,那么不管它是不是国际先进水平,都会遭到一些人的嘲笑。在对本国本民族的成果如此苛刻的同时,很多人却非常崇拜与相信外国人的浮夸宣传。

开源GPL的“集市人海战术”真的有效吗?
GCC真的是它自颂的什么“我们这个星球上最先进的编译器”吗?(怎么感觉这话象外星人的语气呢)
Linux真的象它宣传的那么“高度稳定可靠”吗?
GNU软件真的是自由软件吗?
GPL协议真的是自由参加的吗?
LINUX中究竟剽窃了多少别人有版权的商业UNIX软件中的源代码?
GNU软件还有那些是抄袭的?
GNU的宣传哪些是学术造假行为?
………

(程序员兄弟们也来帮忙写吧,我一个人势单力薄,我们所有的人都处在GPL的威胁下,不要等它欺负到你时你才开始反抗)

我曾经感到很奇怪,GPL是怎么发展到这一步的呢?势力竟然这么庞大,可是所宣扬的又是如此的不合理。
GPL要让程序员开放源代码,而且任何人只要使用了GPL的代码就必须把整个软件全部开源,GPL的这种传染性本质上是病毒是瘟疫。

GNU GPL最具欺骗性的是它一边标榜自愿参加,你不愿意可以不参加,一边标榜参加者是道德高尚的,一边又诋毁做商业软件的是魔鬼,三方面同时抓,它的宣传非常强。这样一来许多参加它的人并不是“自愿参加”的,而是被它自己所定的所谓道德逻辑强制参加的,“自愿参加”只是一个虚伪的幌子。
几乎所有的邪教都说自己的教徒是“自愿参加”,可你要是不参加他们就会对你恶言相加,因为它把参加与否定为了所谓的“道德”。这样的“自愿参加”本质是“强制参加”。

加入容易,想退出可难了。邪教的教徒们疯狂传教,RMS的信徒们狂热劲丝毫不亚于此,他们宣称自由加入GPL还可以自由退出,可是等你想退出时却发现不仅会面临“道德”上的压力,GPL本身就对你有非常无理的限制:你以前按GPL发布的代码根本不让你带着,你光屁股走人吧。

GNU GPL本质上非常类似传销。但是其危害远远超过传销。

GNU一开始上来就号称自己是“自由软件”,那个好自扮耶稣让信徒拜他的开源GPL领袖RICHARD STALLMAN对中国的“自由”二字表示有不只免费的意思时非常得意,很长时间里GNU就打着“自由软件”的旗号宣传自己欺骗别人,等到后来发现有点不灵了呢,立刻改口说:“GNU软件也是有版权的,不是自由的”,但是它同时仍然打着“自由软件”的旗号,那么我要问:你到底是自由的吗?如果不是自由的,为什么要盗用自由这个词?可是如此明显的骗局竟然能在全世界吃得开。而且GPL在这里又耍了一个骗局,GNU软件有版权倒是有版权,只是这版权并不是属于你,是属于GPL。

朋友啊,记住吧:
如果GNU说你可以“自愿参加”,你就要知道它幕后是要强制参加的;
如果GNU说你可以“自由出入”,你就要知道它是进去容易出来难;
如果GNU说它的软件是“自由软件”,你就要知道它其实是“非自由软件”;
…………
总之无论GNU说它自己是什么,你就认为它极可能不是什么——哪怕哪天GNU忽然说它死了,你一定要记住其实那是它没死才那样说的,赫赫。

GNUer诋毁微软说微软的成功不是靠技术,是靠商业吵作与机遇,其实GNU今天的所谓成功才不是靠技术,而是靠欺骗性宣传。现在的LINUX内核中优秀的源代码中有多少代码是开源社区开发的?如果不是IBM的投入,LINUX能有今天的风光吗?而且IBM很大程度上是为跟MS、SUN竞争才这样做的。那么这样的功绩能算在GNU头上吗?能说是开源社区的贡献吗?再说了,Linux人海战术式的打法即使胜过了Windows也是胜之不武吧。甚至 SCO指控IBM是在违反源代码许可协议向LINUX提供源代码,这样的事以后再说。

GCC也是如此,GCC宣称是“我们这个星球上最先进的编译器”,其实这是“我们这个星球上的一大谎言”,说白了GCC跟VC差远去了.不要拿标准支持程度与支持CPU种类多少来说事,那比较不出编译器设计本身真正的水平来。不说代码优化,不说编译速度,单开发环境VC就是EMACS/GDB /GUD没法比的,(有人说高手不用IDE用VIM|EMACS,那EMACS是干什么的?也别用了)当然IDE倒不是语言本身的一部分。

一些GNUer们污蔑微软没技术,说这话的没一点职业道德,其实他们才是没技术,而且即使有技术也不是可以这样说的吧。

GNUer口头上说自由,其实内心专制至极,大家看论坛上的贴子就可以知道,这些人总是一边骂别人,一面禁止一切异见,总是他们骂BILL GATES可以,BILL GATES 的FANS们要是一反驳立刻就遭到围攻。在GPL领袖们的教导下,在对邪教狂热的崇拜中,GNUer们充分的体现了人性中恶的一面,看他们的发言,是IT 人中素质最低下的(一会你看我这个贴子的跟贴,不过我这样说明了他们再表现好也不算了)。凭什么允许他们说BILL GATES的坏话就不许我们反击呢?我这里就说:“BILL GATES是大英雄,RMS才是真正的魔鬼”。而且GNUer们那么多人攻人家MS一家未免太欺负人了吧,以多欺少仗势欺人,真卑鄙。

我发现国人总是对自己人太苛刻,说WPS模拟了MS OFFICE就是抄袭,却不说Linux模拟了UNIX是抄袭;WPS没有抄一句MS OFFICE 的源代码,可是LINUX抄袭了无数未经授权的UNIX源代码,但是在宗教狂热的GNUer们的围攻下,几乎根本不给SCO任何机会。error.h连注释与名字都相同的代码明显就是抄袭嘛,LINUS专门为此与内核的顶级开发人员在网上商讨对策,然后公布出来说那是程序自动生成的,那程序生成器是谁给的,再说这么常用的东西不至于程序生成而且还跟UNIX的版本一样吧,漏洞百出的回答,此地无银三百两;这事要是在中国网上宣传是学术腐败一宣传一个准,麒麟才光部分接口部分反汇编相似与可替换内核启动就被说成是抄袭,LINUX把抄袭的源代码公布了却还不被说成是抄袭呢,从这里看西方法律漏洞太多了,太讲究“证据”,结果就被LINUX钻空子说证据不足。要是SCO到咱中国来打官司可好办了,管它个是不是,有嫌疑就先在网上宣传让老百姓先把这LINUX 骂一通再说事,这LINUX可是几乎完全跟UNIX接口一致,UNASM代码很多也一样啊,当时凭这些就说麒麟是抄袭怎么就不说linux抄袭呀。国人花那么多时间想证明麒麟系统是抄袭的(花的时间都完全可以做一个自己的操作系统了),最后又得到了什么?怎么不花同样的时间去看看LINUX是不是抄袭的呢?千方百计想证明麒麟操作系统是抄袭的人不要外松内紧啊,也去找找LINUX哪出漏子啦。

我们的麒麟OS开发人员肯定很辛苦的,做为中国人应该对我们同胞的工作表示鼓励,而不是思维定势首先怀疑。我认为麒麟OS能用FREEBSD内核替换启动并不能证明麒麟OS就是抄袭的。反而充分证明了麒麟OS不是抄袭的,因为抄袭者必定心虚,必定至少做到内核替换则不能启动(这根本用不了几句话,很简单),否则这漏洞太大了吧,敢唱空城计的可不是一般的啊。那么目前保持内核兼容性的原因是什么呢?可能是为了把FreeBSD上许多软件都迅速移植过来,而不是再重新开发。

即使麒麟OS真是抄袭的,能够达到安全需求也已经足够了。可不象麒麟OS开发人员,LINUX的开发人员是抄袭老手,从SCO第一次警告开始已经让他们有免疫力了,肯定会做到让一般人不怎么能看出来。现在想让SCO提供严格的新证据恐怕是很难的,因为LINUX的开发人员必定把相关的证据全部抹去。除非SCO有一些极高极厉害的技巧,西方法律的死板又是众所周知的。假如有一天老骂麒麟OS的终于知道了LINUX高级技术全是抄袭的,再回想一下自己对麒麟OS的态度,真不知……同为抄袭,为何是两种待遇啊?怪不得丘成桐说中国人嫉妒别的中国人做出成绩。

中国很多网友对中国公司剽窃与GPL剽窃为什么是两种态度呀?中国公司剽窃外国的遭到批判,怎么外国人剽窃就成了英雄呢?这很明显的不合理嘛,这怪GNUer们太会蛊惑人心了。真是“窃钩者诛,窃国者为诸侯”。

不要老是说中国人好撒谎,外国人更会撒谎,不要说外国人比中国人怎么高尚,很多外国人道德比中国人低劣。LINUX里用了SCO的代码,这是每一个 LINUX核心开发人员都知道的秘密,可是他们却默契守秘,达到一种可怕的程度,GNUer们用尽一切办法抹去证据,再抄袭源码,SCO稍有不满就遭到他们全世界的围攻,而且这种围攻带有极端邪教色彩,他们欺骗了那么多人,也许其中包括你,可是你想过没有,如果未来有一天你也遭到了GNU世界霸权这样的欺负时怎么办?是的,GNU已经开始形成了世界霸权。为了掩盖他们剽窃源代码的罪行,他们对SCO用种种手段造谣攻击,包括种种网络技术上的不文明手段,而在其圈子里知道是哪个团体干的却又严守秘密,其中包括RMS,LINUS,ERIC……——这哪里是什么“自由软件”?这是黑社会!(GPL令人触目惊心的事实请见《SCO发表CEO给源代码开放社区公开信的官方中文版》http://blog.csdn.net/universee/archive /2006/07/07/887619.aspx,可是在GNUer的霸权下这些事实却被掩盖了)

可是为什么国人却普遍去支持一个强盗而讥讽一个受伤的弱者呢,仅仅因为那个强盗把赃物开公共展览会了吗?GPL盗窃千千万万行代码都没人管,凭什么要遵守一个强盗逻辑指责我们中国厂商不遵守GPL协议使用GPL代码呢?那是赃物啊。以前对GPL的支持其实严重阻碍了中国软件的发展,支持SCO更有利于我们,支持SCO,GPL代码大家想拿多少就拿多少,这本来就是GPL从SCO抢的嘛,我们给SCO抢回来还不行吗?以后国内厂商可以光明正大使用 GPL代码了,再也不用偷偷摸摸的啦,哈哈。GPL要是想告我们中国公司盗用他们的源代码,我们就反问“你们盗用SCO的源代码怎么不说了呢?”SCO,到我们中国来打官司吧,或者干脆把公司整个搬过来吧,中国人民保证让SCO乐翻。

其实SCO提出的证据已经早就完全足够了,任何一个基本的程序员都明白注释一样意味着什么——近0概率事件的发生就是几近必然的了。可是西方那种僵化的法律对GNU是没办法的,法官每次对SCO的驳回根本不能证明GPL没剽窃,只能证明西方法律的虚伪与GPL的卑鄙,这是西方法律的耻辱。我们要以中国特色反击GNU。下一篇,将是对GNU国际霸权进行纵深攻击的方案。

拒绝GPL,从你我做起,反抗霸权,中国必胜!

弟兄们,行动吧。

谈论 转贴,但跟我无关.

 

引用

转贴,但跟我无关.
 
 
我要找个女孩儿,温柔点儿,别没事老跑夜店酒吧混.
平常没事儿的时候能找个闹中取静的地方聊会儿.
我讲笑话的时候,偶尔给个眼神,提醒我在听我说话,别管逗不逗,都能笑一下.
吃饭的时候,想点什么就点,别默默济济的.
困了的时候就靠在我肩膀睡会,不带打呼噜的.
出去玩儿,开车回家的路上,能拉拉手,有收费的过来,说一句"我有零钱",当然不让你出了.
喜欢热闹,我有朋友来了,给个面儿,别拘着.
一定要是北京人,别动不动就说我听不懂的话,也别说我说话你听不懂,英语除外.
有个正当工作,挣钱多少都行,别认识半年了,发现是全世界的男人都认识你.
穷点儿就别每天换个LV什么的,有钱的也低调点儿.
晚上睡不着的时候,别管几点,拿起电话打就是了,我闷的时候你陪我,你闷的时候陪你事我的义务.
我在海淀,你在朝阳的时候,我要是叫你出来玩儿,要没事儿别让我接你了,你要说真有事我能不接吗,本来几十快钱打的就来了,到了门口我肯定准时在哪等着掏车钱.
我哪儿做错了,第一个告诉我,别让别人先知道,又不是六方会谈,还要统一意见.
有的时候,做错了,当事人不一定真知道,当然了,该骂就骂,最好别动手,你肯定练不过我,一般象这种事儿,我肯定听你骂完跟你道歉.
还有别有事没事儿,借故翻别人手机,QQ五六的,没那么多作怀不乱的,说个宝贝儿,发个吻什么的,我觉得正常,当然了激情视频一定要制止.
说了这么多我可不是找女朋友,所以有男朋友的也无所谓,最好开朗点的,最低也是爱笑的.上次遇到一姐们儿,我说了3小时不说话,不笑的,哎,越看越觉得她象杜沙夫人她家里人.
吃饭,唱歌,跳舞,买零食,哪怕是女生专用的哪种纸,不用抢着卖单,我来买.但别没事就拉着我跑国贸王府什么的,多可怕啊,那么多希奇古怪的人在挑希奇古怪的东西,还动不动就用希奇古怪的眼神瞟你,搞的好象我长的多希奇古怪的似的.
不管在哪碰见熟人,大大方方的说是朋友就完了,别哥哥弟弟老公什么的,下次我在碰见那人,真记不住.
约好去哪的时候难免有个变动什么的,想去就去不想去就别去,我第一时间赶回来找你,当然挨骂是肯定的了,毕竟作错了,千万别在人多的地方吵架,多尴尬啊,咱们又不是动物,凭什么让他门看真人电影啊,要你真生气,我就真敢大声说:"今天就拍到这里吧,换个场景."不开玩笑.我就"好"(四声)面儿.
9月12日

政府的番茄花园

    近日,在番茄销售市场疲软的情况下,贵州省贵阳市白云区委办公室和区政府办公室联合下发红头文件,要求辖区各单位干部职工每人购买100斤番茄。(8月31日《贵州都市报》)

    “包揽一切”很容易造成滥权

    某种程度上,面对行情不好的番茄销售市场,有的地方
政府不惜背负滥用行政权力的骂名匆忙“救市”,实属“不得已而为之”之举,其暴露出的其实是当前政府在管理和指导农业生产过程中存在的某种共性问题。

    一段时间以来,不少地区都有“一哄而上”的习惯,不考虑本地实际,不问效益升降的结构调整,显然并不是农业结构调整的最终出发点。不仅如此,有些地方政府单纯地用静态的眼光看待动态的市场,无视农业种植的周期效应和“蛛网效应”,极易造成市场饱和,使俏销产品成为滞销货,政府最后不得不亲自“救火”。

    更为关键的是,一些地方特别是个别乡镇一级政府仍在延续“政府包揽一切”的做法,把自己的主观愿望强加到农民头上,要求农民种植这个,减少那个;甚至有的地方政府把调整农业种植结构搞成了自身的“政绩工程”,如果产品滞销,政府也常常滥用行政权力拆东墙补西墙甚至饮鸩止渴。事实上,在农业结构调整的问题上,农业结构调整的主体应该是农民,其逐利的本性是结构调整得以深入开展的基本动力,政府不宜也不应当一味地运用行政措施,而必须尊重农民群众的自主选择。 □王小莉

    行政的尊严在于为民所用

    只依靠市场调节的力量就能让菜农的番茄销售找到出路,当然是我们希望看到的结局。不过务实些看,这样的希望只能是奢望。救急如救火,对那些投入和辛苦一季,如今却只能面对一地番茄欲哭无泪的菜农来说,还有什么比解决番茄销路更迫切需求的呢?因此,白云区此举虽然不合乎一般的权力叙事规则,但是如果不突围,番茄的销路何在?不断扩大的菜农损失又该如何降低?

    但是,必须承认,我们需要规避权力越位运用的机制约束和程序规范。可是否有人注意到,程序和机制束缚越刻板,就越不可能照顾到复杂多变的社会现实。所谓过犹不及,一旦程序和机制在社会运行过程中被过分强化,行政行为本身社会的,就只剩下僵硬和冰冷,而不能充分表达对贫弱者的悲悯和同情。不妨设想,如果该事件中,当地政府的权力运用不敢越雷池半步,自然没有招致越位用权非议的担忧,但是其沉重代价是更多番茄烂在地里。

    行政的全部尊严在于为民所用,为民的前提条件在于悲悯贫弱。无视民生疾苦,再合乎规则的权力叙事都会黯然失色。反之,纵然看上去不那么优雅,只要以消解民生疾苦为出发点,都值得给予掌声。 □赵登岩

三鹿毒奶粉之国家质检总局(二)

    石家庄三鹿集团股份有限公司11日晚发布产品召回声明,称经公司自检发现2008年8月6日前出厂的部分批次三鹿婴幼儿奶粉受到三聚氰胺的污染,市场上大约有700吨。(9月1

1日新华网)

    什么是“三聚氰胺”?据卫生部专家介绍,这是一种重要的有机化工中间产品,主要用于装饰板的制作。如果长期摄入三聚氰胺会造成生殖、泌尿系统的损害,膀胱、肾部结石,并可进一步诱发膀胱癌。由此可见,它对人体的损害是很大的。

    那么三鹿品牌作为国家免检产品,它的婴幼儿奶粉为什么会与这种工业原料扯在一起 呢?对此,三鹿集团至今还未有正式的说法。笔者在网上搜索后得知,三聚氰胺分子中含有大量氮元素,添加在食品中,可以提高检测时食品中蛋白质检测数值。而 我国现行的主要奶粉标准是国家质量技术监督局发布的GB5410-1999《全脂乳粉、脱脂乳粉、全脂加糖乳粉和调味乳粉》。该标准与原标准突出的不同是 规定了蛋白质含量,并且所规定的蛋白质含量高于国际标准1到2个百分点,目的是促使企业向国际标准靠拢,保证产品达标。

    三鹿婴幼儿奶粉究竟是受到三聚氰胺“污染”还是人为的“有意为之”,笔者不敢 妄加猜测,相信国家相关部门经过详细调查后会给出一个明确的说法。但不能不问的是,三鹿奶粉造成如此重大的食品安全事故,它之前的“国家免检产品”称号是 如何拿到的?国家相关部门又是凭什么授予它“国家免检产品”称号的?对于“国家免检产品”,相关部门难道真的不再检查了么?

    对老百姓而言,买东西时都图个质量好,用着放心。特别是对于食品安全问题,人 们的期待更高,于是才有了国家免检产品、绿色环保标志等国家质量认证。而各大企业争着往自己“脸上”贴这个标签,就是出于老百姓对这类质量认证的认可,进 一步说就是老百姓对国家质量监督部门的充分信任。而事实上,大部分贴着国家质量认证标签的产品,也都以过硬的质量赢得了老百姓的良好口碑。

    然而,此次的三鹿婴幼儿奶粉事件,无疑会对我们的质量认证体系造成恶劣影响, 使民众对“国家免检产品”这块金字招牌产生信任危机。要知道,国家的质量监督系统不仅仅应当对民众负责,更应当对企业负责。一个品牌的成长是需要付出很多 人的心血的,作为企业有责任对自己的品牌负责,不能为了利益而泯灭了良心;作为质量监督部门,更应该用高度的责任心担负起质量监督的重任,不能因为发了“ 招牌”就什么都不管了。

    教训是深刻的,但如果能及时总结教训才弥足珍贵。作为一名普通的消费者,笔者恳请那些质量监督部门赶快负起责任,不要再让我们的孩子受到这种伤害了。

三鹿毒奶粉之国家质检总局

  本报讯 (记者周照 欧志葵) 近日,多个省市出现婴儿长期服食三鹿奶粉后患肾结石的投诉,迅速在全国掀起轩然大波,怒不可遏的网友们强烈要求揪出“元凶”。而患儿家长们纷纷反映,孩子 都是长期喝着一款“三鹿”牌婴儿奶粉。身为国产奶粉行业一哥的河北石家庄三鹿集团顿时陷入前所未有的质疑声浪中。

  而记者昨日了解到,今年6月,国家质检总局食品生产监管司网站就已有消费者投诉婴儿吃三鹿奶粉后患肾结石。

  事态发展 结石患儿涉及十个省份

  6月28日,位于甘肃省兰州市的中国人民解放军第一医院泌尿科收到第一例婴儿患有“双肾多发性结石”和“输尿管结石”的病例。至9月8日,该院三个多月来共收治14名患有同样疾病病例的婴儿。截至昨日,有6名在手术后康复出院,其余8名仍在医院治疗。

  此前,湖北省同济医院小儿科也接收了三名患有肾病的婴儿,分别来自河南、江西和湖北。

  南京市儿童医院泌尿外科日前也接诊了20名吃同一品牌奶粉患上肾病的患儿。病情严重的已转至上海治疗。

  到目前为止,已发现的数十名患儿共涉及湖北、湖南、山东、安徽、江西、江苏、陕西、甘肃、宁夏、河南等十个省份。

  记者追寻 6月投诉的内容已被隐藏

  据网友介绍,在国家质检总局食品生产监管司的“留言查询”版内,6月30日就有消费者报料,在湖南儿童医院,有5名婴儿得了肾结石病,其中一个 6个月,一个8个月,一个10个月。而且这些患病婴儿长期吃的是同一个品牌奶粉。该投诉者在留言板上还急切地说:“请尽快查清奶粉是否有问题,为避免更多 婴儿得此病。”

  记者昨日在国家质检总局食品生产监管司官方网站的留言查询里,确实查询到有编号为“20080630-1622-25262”的投诉。不过,该投诉的内容已被隐藏,但回复仍在。食品生产监管司在7月2日的回复是,“请你提供问题奶粉的详细信息,以便我们调查处理。”

  在9月6日、9日的留言里,记者发现均有消费者向国家质检总局反映有婴儿因长期服食奶粉而患肾结石。该消费者还表示:“强烈希望你们能检验此品 牌奶粉的质量,以免更多的孩子再受其害!”当时,国家质检总局回复称,该局正在严重关注此事,并联合有关部门积极调查处理。同时,该局还建议消费者,“请 你也将详细信息向卫生部门反映”。

三鹿毒奶粉

http://news.sina.com.cn/c/2008-09-12/103916280477.shtml

  “我的本意是宣传科室的技术,但凭良心不能不提奶粉的事。”昨晚,同济医院小儿外科副主任张文接受记者采访时,仍有些低调。

  个子瘦瘦,浓黑的眉毛下架着一副眼镜,说话时眼神坚定。16天前的8月27日,如果不是他第一个说出“高度怀疑三鹿奶粉可能导致婴儿肾结石”,可能“三鹿奶粉事件”还会延时爆发。

  据张文讲,近1年来,该科陆续接治小儿肾结石患儿,由于这些患儿都吃过同一个品牌的奶粉,因此他的神经高度敏感。而就在这一年前后,上海一家医院的同行也发现类似情况,但一直只是在小范围里议论交流,没有人公开说破。

  张文说,1岁以下婴儿肾结石本身就很罕见,而这在1年之内病例突然增加,让他越来越感到不安,“这样下去不是件好事情”。于是,在8月27日,他在宣传该科医疗技术的同时,向媒体说出了压在心头许久的重负。

  此后不久,全国各地陆续公开曝出“结石奶粉事件”。(记者卢水平)

三鹿毒奶粉

http://news.sina.com.cn/c/2008-09-12/020716276232.shtml

  (本报,是指新京报)

    本报讯 (记者徐春柳)昨天,中国家具协会副秘书长朱长岭介绍,三聚氰胺一般来说是用来制造板材的化工原料,怎么会出现在奶粉当中,不好推断。“用于家装上并无毒性,但口服就不好说了。”

  一名不愿具名的化工专家介绍,三聚氰胺其分子中含有大量氮元素。用普通的全氮测定法测饲料和食品中的蛋白质数值时,根本不会区分这种伪蛋白氮。添加在食品中,可以提高检测时食品中蛋白质检测数值。

  有媒体此前报道,某些饲料加工厂,会往饲料中添加三聚氰胺这种化工原料。这样可以冒充成高蛋白饲料,还能大幅度降低成本。去年,在美国发生了猫狗宠物非正常死亡事件,美国有关部门经过调查确认是宠物食品的原料受三聚氰胺污染。

  去年5月9日,国家质检总局在通报两家企业因其部分出口的小麦蛋白粉和大米蛋白粉中,蛋白含量不能达到合同的要求,违规添加了三聚氰胺。

9月11日

zz常用光学设计软件

 

引用

常用光学设计软件
zemax用的比较多,此外code v和北理的sod88也有人用。oslo比较专业,国内用的人就比较少了。
 
常用软件介绍
 
ZEMAX
    ZEMAX是美国焦点软件公司所发展出的光学设计软件,可做光学组件设计与照明系统的照度分析,也可建立反射,折射,绕射等光学模型,并结合优化,公差等分析功能,是套可以运算Sequential及Non-Sequential的软件。版本等级有SE:标准版,XE:完整版,EE:专业版(可运算Non-Sequential)。ZEMAX的主要特色:分析:提供多功能的分析图形,对话窗式的参数选择,方便分析,且可将分析图形存成图文件,例如:*.BMP,  *.JPG...等,也可存成文字文件*.txt;优化:表栏式merit function参数输入,对话窗式预设merit function参数,方便使用者定义,且多种优化方式供使用者使用;公差分析:表栏式Tolerance参数输入和对话窗式预设Tolerance参数,方便使用者定义;报表输出:多种图形报表输出,可将结果存成图文件及文字文件。
                               
                               
CODE V
    CODE V:是世界上应用的最广泛的光学设计和分析软件,近三十多年来,Code V进行了一系列的改进和创新,包括:变焦结构优化和分析;环境热量分析;MTF和RMS波阵面基础公差分析;用户自定义优化;干涉和光学校正、准直;非连续建模;矢量衍射计算包括了偏振;全球综合优化光学设计方法。
                               
                               
OSLO
    oslo是一套标准建构系统及最佳化的光学软件。最主要地,他是用来决定光学系统中最佳组件的大小和外型,如照相机、客户产品、通讯系统、军事/外层空间应用以及科学仪器等。除此之外、他也常用于仿真光学系统性能以及发展出一套对光学设计、测试和制造的专门软件工具。
                               
LENSVIEW
    LensVIEW为搜集在美国以及日本专利局申请有案的光学设计的数据库,囊括超过18,000个多样化的光学设计实例,并且每一实例都显示它的空间位置。它搜集从1800年起至目前的光学设计数据,这个广博的LensVIEW数据库不仅囊括光学描述数据,而且拥有设计者完整的信息,摘要,专利权状样本,参考文件,美国和国际分类数据,和许多其它的功能。LensVIEW并能产生各式各样像差图,做透镜的快速诊断,和绘出这个设计的剖面图。
                               
                               
ASAP
                                 
    ASAP是功能强大的光学分析软件,是专为仿真成像或光照明的应用而设计,让您的光学工程工作更加正确且迅速。ASAP让您在制作原型系统或大量生产前可以预先做光学系统的仿真以便加快产品上市的时间。传统描光程序的速度是非常烦琐秏时的。ASAP对于整个非序列性描光工具都经过速度的优化处理,让您可以在短时间内就可做数百万条几何描光的计算。光线可不计顺序及次数的经过表面,还可向前,向后追踪。此外ASAP具有强大的指令集可以让您进行特性光线以及物体的分析,包括:选择你所要分析的物体上的光线;选择并独立出特定的光线群;列出光线的来源(折射/反射/散射…)与以及其路径的变化;追踪光线的来源以及强度,分析出您意想不到的杂散光路!
                               
                               
TRACEPRO
    TracePro是一套普遍用于照明系统、光学分析、辐射分析及光度分析的光线仿真软件。它是第一套以ACIS Solid Modeling Kernel为基本的光学软件。也是第一套结合真实固体模型、强大光学分析功能、数据转换能力强及易上手的使用接口的仿真软件。 TracePro多变化的应用领域包括: 照明(Illumination);导光管(Light Pipes);薄膜光学(Tissue Optics);光机设计(Optomechanical Design);杂散光和激光泵浦。
                               
                               
TFCALC
     一个著名的光学薄膜设计软件,有超过35个国家的工程师和科学家用它进行膜系设计。许多光学元件需要多层膜系设计,如棱镜、显示器、眼镜片等。为了控制从X射线到远红外线的波长范围内的光的反射和透射,光学薄膜取决于它需要如何控制光的干涉和吸收,TFCalc让您轻松的设计出您的光学系统中光学元件所需的薄膜层。
                               
                               
OPTISYS_DESIGN
    OptiSys_Design是一种开创性的光通信系统仿真软件包,用于在大部分光网络物理层上绝大多数的光连接形式(包括从模拟视频广播系统到洲际骨干网)的设计、测试和优化。作为系统级的基于实际的光纤-光通信系统仿真器,它实现了强大的仿真环境和对与系统以及器件的之间层次等级的真实界定。作为客户还可以方便的把自己定义的器件无缝的加入到通用器件之中以扩展其功能。客户可以用图形用户界面来控制光器件的摆放和连接,器件的模型和示图。器件库中广泛的包含有源和无源的器件,包括它们实际上随波长而变的参数表。参数环表同样可以使客户查到特定器件的规格对于整个系统性能的影响。
                               
                               
OPTIAMP_DESIGN
    使用于EDFA工程师面临的从光器件搭配优化到系统互联和功率损耗的估计的各个应用方面。通过最小输出功率、最大噪声指数、最大增益抖动、最小泵浦功率这些依赖于器件的规格(泵浦波长范围、无源器件损耗和器件价格)的计算,可以很大程度上协助权衡EDFA的价格和性能。软件所支持的功能包括用于单信道或WDM网络的单一或多重放大器;反射的,分离信道区间,双向和增益带门限的放大器,环状线性光纤放大器,还有宽带光源。软件利用代数学优化可以自动得到参铒光纤的长度,增益平坦光纤的频谱或WDM信道的预增益,同时还仿真了电路反馈,从而维持全部信道所需的泵浦功率以及保证各个信道的功率可以控制。
                               
BPM_CAD
    BPM_CAD是一种强大的,界面友好,应用于各种集成器件和光纤导波计算的计算机辅助设计软件包。
                               
                               
IFO_GRATINGS
     IFO_Gratings是用于带有光栅的集成或光纤器件建模的强大而界面友好的设计软件。许多远程通信和传感器的运转都是利用光栅来调节光导模式之间的耦合。客户只须简单的选择其中一项即可设定器件参数。
                               
                               
FIBER_CAD
    Fiber_CAD是为设计或使用光纤、光器件和光通信系统的工程师、科学家和学生们推出的,此软件包通用、强大,通过融合光纤色散、损耗和偏振模色散(PMD)各个模型计算所得的数值解来解决光纤模式传输问题。
                               
                               
HS_DESIGN
    一个动态的计算机辅助工程程序,通过基于物理层对异质结结构电学光学的特性仿真来协助半导体光器件的设计。HS_Design利用对各个半导体层的精微仿真来分析生长时晶体外延结构的光学特性,包括缓冲、分隔、蚀刻、接触、覆膜和金属化层。客户只需定义材料系统(例如,砷化镓铝/砷化镓或砷化镓磷铝/磷化铝)和半导体层的技术参数(成分、宽度和聚集掺杂浓度),则不仅能计算分层的自由载流子参数(净浓度和有效温度)所表示的电子能带结构和复介电常数,光受复合多层结构的作用也可以表示。如果该结构表示的是纵向层叠结构,那么传输,反射和吸收频谱也可以得到。如果被仿真的结构是一个平坦的波导,那么横断模特性也能计算。
                               
FDTD_CAD
                                 
    FDTD_CAD是用于高级有源和无源光器件的计算机辅助设计的强大而界面友好的软件。FDTD_CAD的理论基础是时域有限元(FDTD)的方法,这种方法可以直接在时域中计算Maxwell方程。与其他必须假定传播场类型或特定的传播方向的方法不同,FDTD方法不对光的传播行为简单的作任何事先假定。结果是,FDTD的计算能够提供任意时间点上整个计算窗内全部或离散的时域信息。如果还需要频域的信息,用离散傅里叶变换(DFT)就可以得到相应的数据。FDTD_CAD软件使用的FDTD方法的强大功能在于它把动态特性整合于一体,可高效率地用于以下模型:光传输,散射,折射,反射,极化效应,材料各向异性,色散和非线性,媒介损耗和增益。
                               
WDM_PHASAR
                                 
     WDM_Phasar软件包提供了基于AWG的光复用分用和路由器件针对性的强大的设计和建模工具。优越的图形用户界面(GUI)大大减低了设计时间,作为核心的能用鼠标控制的布局设计器包含有一整套导波阵列模板以便最大限度的辅助设计。
 
--------------------------------------------------------------------------------
缺陷模        如果在一个存在完全禁带的理想光子晶体中引入点缺陷,那么在禁
带中将会存在一个或者多个振动模,这称为缺陷模,缺陷模的性质在激光器,
谐振腔,波分复用方面有潜在的应用前景
9月9日

CPU 18条知识

1.主频

  主频也叫时钟频率,单位是MHz,用来表示CPU的运算速度。CPU的主频=外频×倍频系数。很多人认为主频就决定着CPU的运行速度,这不仅是个片面的,而且对于服务器来讲,这个认识也出现了偏差。至今,没有一条确定的公式能够实现主频和实际的运算速度两者之间的数值关系,即使是两大处理器厂家 Intel和AMD,在这点上也存在着很大的争议,我们从Intel的产品的发展趋势,可以看出Intel很注重加强自身主频的发展。像其他的处理器厂家,有人曾经拿过一快1G的全美达来做比较,它的运行效率相当于2G的Intel处理器。
  所以,CPU的主频与CPU实际的运算能力是没有直接关系的,主频表示在CPU内数字脉冲信号震荡的速度。在Intel的处理器产品中,我们也可以看到这样的例子:1 GHz Itanium芯片能够表现得差不多跟2.66 GHz Xeon/Opteron一样快,或是1.5 GHz Itanium 2大约跟4 GHz Xeon/Opteron一样快。CPU的运算速度还要看CPU的流水线的各方面的性能指标。
  当然,主频和实际的运算速度是有关的,只能说主频仅仅是CPU性能表现的一个方面,而不代表CPU的整体性能。( bbz888.mcublog.com )

2.外频

  外频是CPU的基准频率,单位也是MHz。CPU的外频决定着整块主板的运行速度。说白了,在台式机中,我们所说的超频,都是超CPU的外频(当然一般情况下,CPU的倍频都是被锁住的)相信这点是很好理解的。但对于服务器CPU来讲,超频是绝对不允许的。前面说到CPU决定着主板的运行速度,两者是同步运行的,如果把服务器CPU超频了,改变了外频,会产生异步运行,(台式机很多主板都支持异步运行)这样会造成整个服务器系统的不稳定。
  目前的绝大部分电脑系统中外频也是内存与主板之间的同步运行的速度,在这种方式下,可以理解为CPU的外频直接与内存相连通,实现两者间的同步运行状态。外频与前端总线(FSB)频率很容易被混为一谈,下面的前端总线介绍我们谈谈两者的区别.( bbz888.mcublog.com )

3.前端总线(FSB)频率

  前端总线(FSB)频率(即总线频率)是直接影响CPU与内存直接数据交换速度。有一条公式可以计算,即数据带宽=(总线频率×数据带宽)/8,数据传输最大带宽取决于所有同时传输的数据的宽度和传输频率。比方,现在的支持64位的至强Nocona,前端总线是800MHz,按照公式,它的数据传输最大带宽是6.4GB/秒。
  外频与前端总线(FSB)频率的区别:前端总线的速度指的是数据传输的速度,外频是CPU与主板之间同步运行的速度。也就是说,100MHz外频特指数字脉冲信号在每秒钟震荡一千万次;而100MHz前端总线指的是每秒钟CPU可接受的数据传输量是 100MHz×64bit÷8Byte/bit=800MB/s。
  其实现在“HyperTransport”构架的出现,让这种实际意义上的前端总线(FSB)频率发生了变化。之前我们知道IA-32架构必须有三大重要的构件:内存控制器Hub (MCH) ,I/O控制器Hub和PCI Hub,像Intel很典型的芯片组 Intel 7501、Intel7505芯片组,为双至强处理器量身定做的,它们所包含的MCH为CPU提供了频率为533MHz的前端总线,配合DDR内存,前端总线带宽可达到4.3GB/秒。但随着处理器性能不断提高同时给系统架构带来了很多问题。而“HyperTransport”构架不但解决了问题,而且更有效地提高了总线带宽,比方AMD Opteron处理器,灵活的HyperTransport I/O总线体系结构让它整合了内存控制器,使处理器不通过系统总线传给芯片组而直接和内存交换数据。这样的话,前端总线(FSB)频率在AMD Opteron处理器就不知道从何谈起了。 ( bbz888.mcublog.com )

4、CPU的位和字长

  位:在数字电路和电脑技术中采用二进制,代码只有“0”和“1”,其中无论是 “0”或是“1”在CPU中都是 一“位”。
  字长:电脑技术中对CPU在单位时间内(同一时间)能一次处理的二进制数的位数叫字长。所以能处理字长为8位数据的CPU通常就叫8位的CPU。同理 32位的CPU就能在单位时间内处理字长为32位的二进制数据。字节和字长的区别:由于常用的英文字符用8位二进制就可以表示,所以通常就将8位称为一个字节。字长的长度是不固定的,对于不同的CPU、字长的长度也不一样。8位的CPU一次只能处理一个字节,而32位的CPU一次就能处理4个字节,同理字长为64位的CPU一次可以处理8个字节。 ( bbz888.mcublog.com )

5.倍频系数

  倍频系数是指CPU主频与外频之间的相对比例关系。在相同的外频下,倍频越高CPU的频率也越高。但实际上,在相同外频的前提下,高倍频的CPU本身意义并不大。这是因为CPU与系统之间数据传输速度是有限的,一味追求高倍频而得到高主频的CPU就会出现明显的“瓶颈”效应デ—ダCPU从系统中得到数据的极限速度不能够满足CPU运算的速度。一般除了工程样版的Intel的CPU都是锁了倍频的,而AMD之前都没有锁.( bbz888.mcublog.com )

6.缓存

  缓存大小也是CPU的重要指标之一,而且缓存的结构和大小对CPU速度的影响非常大,CPU内缓存的运行频率极高,一般是和处理器同频运作,工作效率远远大于系统内存和硬盘。实际工作时,CPU往往需要重复读取同样的数据块,而缓存容量的增大,可以大幅度提升CPU内部读取数据的命中率,而不用再到内存或者硬盘上寻找,以此提高系统性能。但是由于CPU芯片面积和成本的因素来考虑,缓存都很小。
  L1 Cache(一级缓存)是CPU第一层高速缓存,分为数据缓存和指令缓存。内置的L1高速缓存的容量和结构对CPU的性能影响较大,不过高速缓冲存储器均由静态RAM组成,结构较复杂,在CPU管芯面积不能太大的情况下,L1级高速缓存的容量不可能做得太大。一般服务器CPU的L1缓存的容量通常在32—256KB。
  L2 Cache(二级缓存)是CPU的第二层高速缓存,分内部和外部两种芯片。内部的芯片二级缓存运行速度与主频相同,而外部的二级缓存则只有主频的一半。L2高速缓存容量也会影响CPU的性能,原则是越大越好,现在家庭用CPU容量最大的是512KB,而服务器和工作站上用CPU的L2高速缓存更高达256-1MB,有的高达2MB或者3MB。
  L3 Cache(三级缓存),分为两种,早期的是外置,现在的都是内置的。而它的实际作用即是,L3缓存的应用可以进一步降低内存延迟,同时提升大数据量计算时处理器的性能。降低内存延迟和提升大数据量计算能力对游戏都很有帮助。而在服务器领域增加L3缓存在性能方面仍然有显著的提升。比方具有较大 L3缓存的配置利用物理内存会更有效,故它比较慢的磁盘I/O子系统可以处理更多的数据请求。具有较大L3缓存的处理器提供更有效的文件系统缓存行为及较短消息和处理器队列长度。
  其实最早的L3缓存被应用在AMD发布的K6-III处理器上,当时的L3缓存受限于制造工艺,并没有被集成进芯片内部,而是集成在主板上。在只能够和系统总线频率同步的L3缓存同主内存其实差不了多少。后来使用L3缓存的是英特尔为服务器市场所推出的Itanium处理器。接着就是P4EE和至强 MP。Intel还打算推出一款9MB L3缓存的Itanium2处理器,和以后24MB L3缓存的双核心Itanium2处理器。
  但基本上L3缓存对处理器的性能提高显得不是很重要,比方配备1MB L3缓存的Xeon MP处理器却仍然不是Opteron的对手,由此可见前端总线的增加,要比缓存增加带来更有效的性能提升。( bbz888.mcublog.com )

7.CPU扩展指令集

  CPU依靠指令来计算和控制系统,每款CPU在设计时就规定了一系列与其硬件电路相配合的指令系统。指令的强弱也是CPU的重要指标,指令集是提高微处理器效率的最有效工具之一。从现阶段的主流体系结构讲,指令集可分为复杂指令集和精简指令集两部分,而从具体运用看,如Intel的MMX(Multi Media Extended)、SSE、 SSE2(Streaming-Single instruction multiple data-Extensions 2)、SEE3和AMD的3DNow!等都是CPU的扩展指令集,分别增强了CPU的多媒体、图形图象和Internet等的处理能力。我们通常会把 CPU的扩展指令集称为"CPU的指令集"。SSE3指令集也是目前规模最小的指令集,此前MMX包含有57条命令,SSE包含有50条命令,SSE2包含有144条命令,SSE3包含有13条命令。目前SSE3也是最先进的指令集,英特尔Prescott处理器已经支持SSE3指令集,AMD会在未来双核心处理器当中加入对SSE3指令集的支持,全美达的处理器也将支持这一指令集。( bbz888.mcublog.com )

8.CPU内核和I/O工作电压

  从586CPU开始,CPU的工作电压分为内核电压和I/O电压两种,通常CPU的核心电压小于等于I/O电压。其中内核电压的大小是根据CPU的生产工艺而定,一般制作工艺越小,内核工作电压越低;I/O电压一般都在1.6~5V。低电压能解决耗电过大和发热过高的问题。( bbz888.mcublog.com )

9.制造工艺

  制造工艺的微米是指IC内电路与电路之间的距离。制造工艺的趋势是向密集度愈高的方向发展。密度愈高的IC电路设计,意味着在同样大小面积的IC中, 可以拥有密度更高、功能更复杂的电路设计。现在主要的180nm、130nm、90nm。最近官方已经表示有65nm的制造工艺了。


10.指令集

  (1)CISC指令集

  CISC指令集,也称为复杂指令集,英文名是CISC,(Complex Instruction Set Computer的缩写)。在CISC微处理器中,程序的各条指令是按顺序串行执行的,每条指令中的各个操作也是按顺序串行执行的。顺序执行的优点是控制简单,但计算机各部分的利用率不高,执行速度慢。其实它是英特尔生产的x86系列(也就是IA-32架构)CPU及其兼容CPU,如AMD、VIA的。即使是现在新起的X86-64(也被成AMD64)都是属于CISC的范畴。
  要知道什么是指令集还要从当今的X86架构的CPU说起。X86指令集是Intel为其第一块16位CPU(i8086)专门开发的,IBM1981 年推出的世界第一台PC机中的CPU—i8088(i8086简化版)使用的也是X86指令,同时电脑中为提高浮点数据处理能力而增加了X87芯片,以后就将X86指令集和X87指令集统称为X86指令集。
  虽然随着CPU技术的不断发展,Intel陆续研制出更新型的i80386、i80486直到过去的PII至强、PIII至强、Pentium 3,最后到今天的Pentium 4系列、至强(不包括至强Nocona),但为了保证电脑能继续运行以往开发的各类应用程序以保护和继承丰富的软件资源,所以Intel公司所生产的所有 CPU仍然继续使用X86指令集,所以它的CPU仍属于X86系列。由于Intel X86系列及其兼容CPU(如AMD Athlon MP、)都使用X86指令集,所以就形成了今天庞大的X86系列及兼容CPU阵容。x86CPU目前主要有intel的服务器CPU和AMD的服务器 CPU两类。

  (2)RISC指令集

  RISC是英文“Reduced Instruction Set Computing ” 的缩写,中文意思是“精简指令集”。它是在CISC指令系统基础上发展起来的,有人对CISC机进行测试表明,各种指令的使用频度相当悬殊,最常使用的是一些比较简单的指令,它们仅占指令总数的20%,但在程序中出现的频度却占80%。复杂的指令系统必然增加微处理器的复杂性,使处理器的研制时间长,成本高。并且复杂指令需要复杂的操作,必然会降低计算机的速度。基于上述原因,20世纪80年代RISC型CPU诞生了,相对于CISC型CPU ,RISC型CPU不仅精简了指令系统,还采用了一种叫做“超标量和超流水线结构”,大大增加了并行处理能力。RISC指令集是高性能CPU的发展方向。它与传统的CISC(复杂指令集)相对。相比而言,RISC的指令格式统一,种类比较少,寻址方式也比复杂指令集少。当然处理速度就提高很多了。目前在中高档服务器中普遍采用这一指令系统的CPU,特别是高档服务器全都采用RISC指令系统的CPU。RISC指令系统更加适合高档服务器的操作系统 UNIX,现在Linux也属于类似UNIX的操作系统。RISC型CPU与Intel和AMD的CPU在软件和硬件上都不兼容。
  目前,在中高档服务器中采用RISC指令的CPU主要有以下几类:PowerPC处理器、SPARC处理器、PA-RISC处理器、MIPS处理器、Alpha处理器。

  (3)IA-64

  EPIC(Explicitly Parallel Instruction Computers,精确并行指令计算机)是否是RISC和CISC体系的继承者的争论已经有很多,单以EPIC体系来说,它更像Intel的处理器迈向 RISC体系的重要步骤。从理论上说,EPIC体系设计的CPU,在相同的主机配置下,处理Windows的应用软件比基于Unix下的应用软件要好得多。
  Intel采用EPIC技术的服务器CPU是安腾Itanium(开发代号即Merced)。它是64位处理器,也是IA-64系列中的第一款。微软也已开发了代号为Win64的操作系统,在软件上加以支持。在Intel采用了X86指令集之后,它又转而寻求更先进的64-bit微处理器,Intel 这样做的原因是,它们想摆脱容量巨大的x86架构,从而引入精力充沛而又功能强大的指令集,于是采用EPIC指令集的IA-64架构便诞生了。IA-64 在很多方面来说,都比x86有了长足的进步。突破了传统IA32架构的许多限制,在数据的处理能力,系统的稳定性、安全性、可用性、可观理性等方面获得了突破性的提高。
  IA-64微处理器最大的缺陷是它们缺乏与x86的兼容,而Intel为了IA-64处理器能够更好地运行两个朝代的软件,它在IA-64处理器上(Itanium、Itanium2 ……)引入了x86-to-IA-64的解码器,这样就能够把x86指令翻译为IA-64指令。这个解码器并不是最有效率的解码器,也不是运行x86代码的最好途径(最好的途径是直接在x86处理器上运行x86代码),因此Itanium 和Itanium2在运行x86应用程序时候的性能非常糟糕。这也成为X86-64产生的根本原因。

  (4)X86-64 (AMD64 / EM64T)

  AMD公司设计,可以在同一时间内处理64位的整数运算,并兼容于X86-32架构。其中支持64位逻辑定址,同时提供转换为32位定址选项;但数据操作指令默认为32位和8位,提供转换成64位和16位的选项;支持常规用途寄存器,如果是32位运算操作,就要将结果扩展成完整的64位。这样,指令中有“直接执行”和“转换执行”的区别,其指令字段是8位或32位,可以避免字段过长。
  x86-64(也叫AMD64)的产生也并非空穴来风,x86处理器的32bit寻址空间限制在4GB内存,而IA-64的处理器又不能兼容x86。 AMD充分考虑顾客的需求,加强x86指令集的功能,使这套指令集可同时支持64位的运算模式,因此AMD把它们的结构称之为x86-64。在技术上 AMD在x86-64架构中为了进行64位运算,AMD为其引入了新增了R8-R15通用寄存器作为原有X86处理器寄存器的扩充,但在而在32位环境下并不完全使用到这些寄存器。原来的寄存器诸如EAX、EBX也由32位扩张至64位。在SSE单元中新加入了8个新寄存器以提供对SSE2的支持。寄存器数量的增加将带来性能的提升。与此同时,为了同时支持32和64位代码及寄存器,x86-64架构允许处理器工作在以下两种模式:Long Mode(长模式)和Legacy Mode(遗传模式),Long模式又分为两种子模式(64bit模式和Compatibility mode兼容模式)。该标准已经被引进在AMD服务器处理器中的Opteron处理器。
  而今年也推出了支持64位的EM64T技术,再还没被正式命为EM64T之前是IA32E,这是英特尔64位扩展技术的名字,用来区别X86指令集。 Intel的EM64T支持64位sub-mode,和AMD的X86-64技术类似,采用64位的线性平面寻址,加入8个新的通用寄存器(GPRs), 还增加8个寄存器支持SSE指令。与AMD相类似,Intel的64位技术将兼容IA32和IA32E,只有在运行64位操作系统下的时候,才将会采用 IA32E。IA32E将由2个sub-mode组成:64位sub-mode和32位sub-mode,同AMD64一样是向下兼容的。Intel的 EM64T将完全兼容AMD的X86-64技术。现在Nocona处理器已经加入了一些64位技术,Intel的Pentium 4E处理器也支持64位技术。
  应该说,这两者都是兼容x86指令集的64位微处理器架构,但EM64T与AMD64还是有一些不一样的地方,AMD64处理器中的NX位在Intel的处理器中将没有提供。( bbz888.mcublog.com )

11.超流水线与超标量

  在解释超流水线与超标量前,先了解流水线(pipeline)。流水线是Intel首次在486芯片中开始使用的。流水线的工作方式就象工业生产上的装配流水线。在CPU中由5—6个不同功能的电路单元组成一条指令处理流水线,然后将一条X86指令分成5—6步后再由这些电路单元分别执行,这样就能实现在一个CPU时钟周期完成一条指令,因此提高CPU的运算速度。经典奔腾每条整数流水线都分为四级流水,即指令预取、译码、执行、写回结果,浮点流水又分为八级流水。
  超标量是通过内置多条流水线来同时执行多个处理器,其实质是以空间换取时间。而超流水线是通过细化流水、提高主频,使得在一个机器周期内完成一个甚至多个操作,其实质是以时间换取空间。例如Pentium 4的流水线就长达20级。将流水线设计的步(级)越长,其完成一条指令的速度越快,因此才能适应工作主频更高的CPU。但是流水线过长也带来了一定副作用,很可能会出现主频较高的CPU实际运算速度较低的现象,Intel的奔腾4就出现了这种情况,虽然它的主频可以高达1.4G以上,但其运算性能却远远比不上AMD 1.2G的速龙甚至奔腾III。( bbz888.mcublog.com )

12.封装形式

  CPU封装是采用特定的材料将CPU芯片或CPU模块固化在其中以防损坏的保护措施,一般必须在封装后CPU才能交付用户使用。CPU的封装方式取决于CPU安装形式和器件集成设计,从大的分类来看通常采用Socket插座进行安装的CPU使用PGA(栅格阵列)方式封装,而采用Slot x槽安装的CPU则全部采用SEC(单边接插盒)的形式封装。现在还有PLGA(Plastic Land Grid Array)、OLGA(Organic Land Grid Array)等封装技术。由于市场竞争日益激烈,目前CPU封装技术的发展方向以节约成本为主。( bbz888.mcublog.com )

13、多线程

  同时多线程Simultaneous multithreading,简称SMT。SMT可通过复制处理器上的结构状态,让同一个处理器上的多个线程同步执行并共享处理器的执行资源,可最大限度地实现宽发射、乱序的超标量处理,提高处理器运算部件的利用率,缓和由于数据相关或Cache未命中带来的访问内存延时。当没有多个线程可用时,SMT 处理器几乎和传统的宽发射超标量处理器一样。SMT最具吸引力的是只需小规模改变处理器核心的设计,几乎不用增加额外的成本就可以显著地提升效能。多线程技术则可以为高速的运算核心准备更多的待处理数据,减少运算核心的闲置时间。这对于桌面低端系统来说无疑十分具有吸引力。Intel从3.06GHz Pentium 4开始,所有处理器都将支持SMT技术。( bbz888.mcublog.com )

14、多核心

  多核心,也指单芯片多处理器(Chip multiprocessors,简称CMP)。CMP是由美国斯坦福大学提出的,其思想是将大规模并行处理器中的SMP(对称多处理器)集成到同一芯片内,各个处理器并行执行不同的进程。与CMP比较, SMT处理器结构的灵活性比较突出。但是,当半导体工艺进入0.18微米以后,线延时已经超过了门延迟,要求微处理器的设计通过划分许多规模更小、局部性更好的基本单元结构来进行。相比之下,由于CMP结构已经被划分成多个处理器核来设计,每个核都比较简单,有利于优化设计,因此更有发展前途。目前,IBM 的Power 4芯片和Sun的 MAJC5200芯片都采用了CMP结构。多核处理器可以在处理器内部共享缓存,提高缓存利用率,同时简化多处理器系统设计的复杂度。
  2005年下半年,Intel和AMD的新型处理器也将融入CMP结构。新安腾处理器开发代码为Montecito,采用双核心设计,拥有最少 18MB片内缓存,采取90nm工艺制造,它的设计绝对称得上是对当今芯片业的挑战。它的每个单独的核心都拥有独立的L1,L2和L3 cache,包含大约10亿支晶体管。( bbz888.mcublog.com )

15、SMP

  SMP(Symmetric Multi-Processing),对称多处理结构的简称,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。在这种技术的支持下,一个服务器系统可以同时运行多个处理器,并共享内存和其他的主机资源。像双至强,也就是我们所说的二路,这是在对称处理器系统中最常见的一种(至强MP可以支持到四路,AMD Opteron可以支持1-8路)。也有少数是16路的。但是一般来讲,SMP结构的机器可扩展性较差,很难做到100个以上多处理器,常规的一般是8个到16个,不过这对于多数的用户来说已经够用了。在高性能服务器和工作站级主板架构中最为常见,像UNIX服务器可支持最多256个CPU的系统。
  构建一套SMP系统的必要条件是:支持SMP的硬件包括主板和CPU;支持SMP的系统平台,再就是支持SMP的应用软件。
  为了能够使得SMP系统发挥高效的性能,操作系统必须支持SMP系统,如WINNT、LINUX、以及UNIX等等32位操作系统。即能够进行多任务和多线程处理。多任务是指操作系统能够在同一时间让不同的CPU完成不同的任务;多线程是指操作系统能够使得不同的CPU并行的完成同一个任务。
  要组建SMP系统,对所选的CPU有很高的要求,首先、CPU内部必须内置APIC(Advanced Programmable Interrupt Controllers)单元。Intel 多处理规范的核心就是高级可编程中断控制器(Advanced Programmable Interrupt Controllers--APICs)的使用;再次,相同的产品型号,同样类型的CPU核心,完全相同的运行频率;最后,尽可能保持相同的产品序列编号,因为两个生产批次的CPU作为双处理器运行的时候,有可能会发生一颗CPU负担过高,而另一颗负担很少的情况,无法发挥最大性能,更糟糕的是可能导致死机。( bbz888.mcublog.com )

16、NUMA技术

  NUMA即非一致访问分布共享存储技术,它是由若干通过高速专用网络连接起来的独立节点构成的系统,各个节点可以是单个的CPU或是SMP系统。在 NUMA中,Cache 的一致性有多种解决方案,需要操作系统和特殊软件的支持。图2中是Sequent公司NUMA系统的例子。这里有3个SMP模块用高速专用网络联起来,组成一个节点,每个节点可以有12个CPU。像Sequent的系统最多可以达到64个CPU甚至256个CPU。显然,这是在SMP的基础上,再用 NUMA的技术加以扩展,是这两种技术的结合。( bbz888.mcublog.com )

17、乱序执行技术

  乱序执行(out-of-orderexecution),是指CPU允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理的技术。这样将根据个电路单元的状态和各指令能否提前执行的具体情况分析后,将能提前执行的指令立即发送给相应电路单元执行,在这期间不按规定顺序执行指令,然后由重新排列单元将各执行单元结果按指令顺序重新排列。采用乱序执行技术的目的是为了使CPU内部电路满负荷运转并相应提高了CPU的运行程序的速度。分枝技术:(branch)指令进行运算时需要等待结果,一般无条件分枝只需要按指令顺序执行,而条件分枝必须根据处理后的结果,再决定是否按原先顺序进行。( bbz888.mcublog.com )

18、CPU内部的内存控制器

  许多应用程序拥有更为复杂的读取模式(几乎是随机地,特别是当cache hit不可预测的时候),并且没有有效地利用带宽。典型的这类应用程序就是业务处理软件,即使拥有如乱序执行(out of order execution)这样的CPU特性,也会受内存延迟的限制。这样CPU必须得等到运算所需数据被除数装载完成才能执行指令(无论这些数据来自CPU cache还是主内存系统)。当前低段系统的内存延迟大约是120-150ns,而CPU速度则达到了3GHz以上,一次单独的内存请求可能会浪费 200-300次CPU循环。即使在缓存命中率(cache hit rate)达到99%的情况下,CPU也可能会花50%的时间来等待内存请求的结束- 比如因为内存延迟的缘故。
  你可以看到Opteron整合的内存控制器,它的延迟,与芯片组支持双通道DDR内存控制器的延迟相比来说,是要低很多的。英特尔也按照计划的那样在处理器内部整合内存控制器,这样导致北桥芯片将变得不那么重要。但改变了处理器访问主存的方式,有助于提高带宽、降低内存延时和提升处理器性能。
9月8日

举报建委某些工作人员以权谋私,抢占限价房

 

引用

转载一篇水木网友文,关于限价房
发信人: sandwyg (ger), 信区: RealEstate
标  题: 举报建委某些工作人员以权谋私,抢占限价房(ZZ)
发信站: 水木社区 (Mon Sep  8 18:01:09 2008), 站内

问题:
1,在海淀区第一次限价房的摇号结果公布后,三居的前13号中就有6个是海淀建委的,而两居的第一号是建设部的,这正常吗?请看后面附件,都是根据海淀建委公示的资料整理出来的。
2,两居第一号的张彩虹,和三居7号的王俊厚,10号李明文,13号薛向平都不是优先户,但是都排在老龄等优先户的前面,这符合建委自己的规定吗?
3,三居6号王晖,11号赵树静和12号张利芳都带非直系亲属(公公婆婆或者岳父岳母)申请,而不带自己的父母申请,这样合理吗?为什么不是他们的配偶做申请人?
4,这些人都是上有老,下有小的,都在建委工作,却都是无房户,而且抽签的结果也是4联号,有这么巧合的事吗?
5,最重要的是,这些人既是申请人,又是审核人,如何保证他们不以权谋私?


要求:
1,强烈要求首先取消以下建委7个人的本次选房资格,资料重审。

6(三居) 王晖
7(三居) 王俊厚
10(三居) 李明文
11(三居) 赵树静
12(三居) 张利芳
13(三居) 薛向平
1(二居) 张彩虹
2,根据利益回避的原则,申请人不能是审核人,所以要求市人大对这些建委系统的申请者重新审核,而且他们的详细信息需要在网站或者报纸上单独再次公示,以取信于民。如果查出他们有弄虚作假,以权谋私的行为,就必须开除其公职,以向人民交待。


方法:
大家都是纳税人,我们有权利要求建委的工作人民老老实实的为人民服务,而不是以权谋私。所以,请大家都团结起来,都向以下部门举报。上次北师大事件,就是因为网友的强烈反对和媒体的曝光,争取了我们的权利。如果我们这次沉默,会使建委的某些工作人员更加肆无忌惮,以权谋私,我们的利益更加被践踏。让我们每个纳税人都发出愤怒的吼声吧!


市建委的互动网站:
http://www.bjjs.gov.cn/tabid/977/ctl/IPF_MoreList/mid/1504/type/1/Default.aspx
市建委监察处举报电话:010-63987624 电子邮箱:zfxxgkjc@bjjs.gov.cn

海淀区政府信箱:
http://61.49.38.22/hdxxweb/app-web/appeal/user_appeal_gz.jsp
海淀区住保办举报电话:010-62551215

新京报电话: 010-67106666
北京电视台举报电话:010-85223518
北京青年报电话:010-65901550

其它举报方式也请大家都提供。

附件
海淀区限价房总排名前14位,海淀建委自家占据7个席位,均有问题
选房顺序号 申请人姓名 身份证号码 备案编号 工作单位 质疑
6(三居) 王晖 362325197008270021 X060800568 海淀区建设委员会 成员含非直系亲属
无房户?
7(三居) 王俊厚 110106196404033033 X060801754 海淀区建设委员会第四房管所 非优先户排在前面
无房户?
10(三居) 李明文 110108196510053137 X060801202 海淀区建设委员会 非优先户排在前面
无房户?
11(三居) 赵树静 110229196705192716 X060800398 海淀建委 成员是否含非直系亲属?
无房户?
12(三居) 张利芳 410781197607034229 X060800694 海淀建委四所 成员含非直系亲属
无房户?
13(三居) 薛向平 210104196802201750 X060800205 北京市海淀区建设委员会 非优先户排在前面
无房户?
1(二居) 张彩虹 340826197309060042 X060800286 建设部信息中心 (无房户?非优先户排在前面) 非优先户排在前面
无房户?

详细信息    
序号 姓名 身份证件编号 户口所在街道 户籍地址 现居住地址 家庭住
房地址 工作单位 家庭人口 家庭成员名单 家庭年收入 总资产万 人均住房面积 家庭
类型
56(第七批公示) 王晖 362325197008270021 万寿路街道 海淀区太平路46号38号3单元362 海淀区太平路46号38号楼3单元362 太平路46号38楼362号 海淀区建设委员会 4 之夫:解良云,之子:解从罡,之父:解希友 103171.00 46.00 0.00 老龄
119(第十一批公示) 王俊厚 110106196404033033 四季青镇街道 海淀区四季青镇西郊机场13楼4单元405号海淀区四季青西郊机场13楼4单元405号 四季青镇西郊机场13号楼4单元405 海淀区建设委员会第四房管所 5 之妻:吕梅,之子:王蒙,之父:王文中,之母:付桂英 103273.08 15.00 0.00  
63(第九批公示) 李明文 110108196510053137 曙光街道 海淀区北四环西路88号74楼3-301 海淀区北四环西路88号74楼3-301 北四环西路88号74楼3-301 海淀区建设委员会 4 之妻:梁瑞君,之女:李艳婷,之父:李宝田 66979.00 14.50 0.00  
91(第七批公示) 赵树静 110229196705192716 西北旺乡街道 海淀区西北旺镇北清路20号2号楼1单元102室海淀区西北旺镇北清路20号2号楼1单元102室 北清路20号2号楼1单元102室 海淀建委 5 之妻:赵秀英,之女:赵茜,之父:赵永清,之母:王爱芹 82793.00 19.00 0.00 老龄
123(第八批公示) 张利芳 410781197607034229 甘家口街道 海淀区新苑街1号院363号海淀区四季青镇93508部队家属院 四季青镇 93508部队家属院 海淀建委四所 4 之夫:吴楚军,之子:吴诚箫,之母:方得梅 87283.00 0.00 0.00 老龄
17(第六批公示) 薛向平 210104196802201750 八里庄街道 海淀区西三环北路101号1号楼701号大兴区黄村61565部队35-3-401 北京大兴61565部队35-3-401 北京市海淀区建设委员会(四所所长) 5 之妻:李志静,之子:薛文礼,之父:薛志明,之母:白玉英 102336.00 12.00 0.00  
112(第六批公示) 张彩虹 340826197309060042 曙光街道 海淀区北四环西路88号31楼1单元401室海淀区北四环西路88号31楼1单元401室 海淀区北四环西路88号31楼401室 建设部信息中心 3 之夫:许小年,之女:许文君 63557.45 8.90 0.00
 
--------------------------------------------------------------------------------------------------------------------------
一直潜意识里反对经济适用房,包括后来又出了个限价房。为啥?不是说政府不应该保障大众民生,而是这种利益往往被各种公务员,国,市沾边的各种人等攫取。说到底,就是被各种有关系有能力的人优先得到。什么四房两厅,低密度的经济适用房,明眼人一看就不是为该得到的人准备的。其实不用看政策也能知道,能买这些房肯定得有个“收入中下”的“凭证”,然而在个税征收制度及其不公开透明的今天,打着工资1000多旗号还不用纳税实则大把发钱的各色单位有的是,自然也能享受个“收入不高,房子得限价”的待遇。同学里面就有招商银行的跟我吹过他们跟税务局关系多么好,每个月象征性的交点税就可以了,各种奖金可都是落实的,当然,各种“中”字头的就更别提了。可怜我们这种光荣的纳税人办个落户都得看着派出所大妈的臭屁脸。
 
嗯,一不小心今儿又不和谐了一把。
9月6日

Unix 简史

Unix 简史

  1965年时,贝尔实验室(Bell Labs)加入一项由奇异电子(General Electric)和麻省理工学院(MIT)合作的计画;该计画要建立一套多使用者、多任务、多层次(multi-user、multi-processor、multi-level)的MULTICS操作系统。直到1969年,因MULTICS计画的工作进度太慢,该计画就被停了下来。当时,Ken Thompson(后被称为Unix之父)已经有一个称为「星际旅行」的程序在GE-635的机器上跑,但是反应非常的慢,正巧也被他发现了一部被闲置的PDP-7(Digital的主机),Ken Thompson和Dernis Ritchie就将「星际旅行」的程序移植到PDP-7上。而这部PDP-7就此在整个计算机历史上留下了芳名。
  MULTICS 其实是"MULTiplexed Information and Computing System"的缩写,在1970年时,那部PDP-7却只能支持两个使用者,当时,Brian Kernighan 就开玩笑地戏称他们的系统其实是:"UNiplexed Information and Computing System",缩写为"UNICS",后来,大家取其谐音,就称其为"Unix"了。1970年可称为是Unix元年。
  1971年,他们申请了一部PDP-11/20,申请的名义是:要发展文书处理系统。该提案被获采纳,他们也发展出了一套文书处理系统 ─ 就是现在Unix操作系统里面文书处理系统(nroff/troff)的前身。有趣的是,没有多久,贝尔实验室的专利部门真的采用了这套系统作为他们处理文件的工具,而贝尔实验室的专利部门也就顺理成章地成为Unix的第一个正式使用者。当时,那部PDP-11/20只有0.5MB磁盘空间。而描述这整个系统的文件被标示为:"First Edition",版本日期是1970年11月。从此以后,Unix的版本就以系统文件的版别来称呼。

UNIX家谱

  UNIX的历史开始于1969年ken Thompson,Dennis Ritchie(即著名的K&G,C语言的发明人)与一群人在一部PDP-7上进行的一些工作,后来这个系统变成了UNIX。它主要的几个版本为:
  V1(1971):第一版的UNIX,以PDP-11/20的汇编语言写成。包括文件系统,fork、roff、ed等软件。
  V4(1973):以C语言从头写过,这使得UNIX修改容易,可以在几个月内移植到新的硬件平台上。最初C语言是为UNIX设计的,所以C与UNIX间有紧密的关系。
  V6(1975):第一个在贝尔实验室外(尤其是大学中)广为流传的UNIX版本。这也是UNIX分支的起点与广受欢迎的开始。1.xBSD (PDP-II)就是由这个版本衍生出来的。
  V7(1979):在许多UNIX玩家的心目中,这是“最后一个真正的UNIX,”这个版本包括一个完整的K&RC编译器,Bourne shell。V7移植到VAX机器后称为32V。
  目前开发UNIX(System V)的公司是Unix System Laboratories (USL)。USL本为AT&T所有,1993年初被Novell收购。Novell于1993年末将UNIX这个注册商标转让给X/Open组织。
  目前为止,UNIX有两大流派:那就是AT&T发布的UNIX操作系统System V与美国加州大学伯克利分校发布的UNIX版BSD(Berkeley Software Distribution)。SVR4是两大流派融合后的产物。1991年底,与System V针锋相对的开放软件基金会(Open Software Foundation)推出了OSF/1。
  现在几种主要的UNIX版本:
  * AIX:IBM的UNIX,是根据SVR2(最近已经出到SVR3.2)以及一部分BSD延伸而来,加上各种硬件的支持。具备特有的系统管理(SMIT)。
  * 386BSD:Jolitz从Net/2 software移植过来的。支持Posix,32位。
  * FreeBSD:1.x从386BSD 0.1而来,FreeBSD 2.x版是用4.4BSD lite改写。
  * HP-UX(HP):旧系统是从S III(SVRx)发展面来,现在是由SVR2(4.2BSD)发展而来,目前是10.x版。
  * Linux(x86):遵从POSIX,SYSV及BSD的扩展,这一点从上页表中即可看出。
  * OSF/1(DEC):DEC对OSF/1的移植。
  * SCO UNIX(x86):SVR3.2,目前影响较大的PC UNIX。
  * SunOS(680x0,Sparc,i386):根据4.3BSD,包含许多来自System V的东西。Sun的主要成果在于:NFS,OpenLook GUI标准,现演变为Solaris 。

  * Ultrix(DEC):根据4.2BSD再加上许多4.3BSD的东西。
  * Xenix(x86):Intel硬件平台上的UNIX,以SVR2为基础,由微软推出。在中国使用较广泛。

先前的一个理想

UNIX系统自1969年Ken Thompson与Dennis Ritchie在美国贝尔电话实验室(Bell Telephone Laboratories)发展出雏形至今,已历经近 30 来年。而 "UNIX"这个字典上查不到其原意的怪字,其实是戏谑 MULTICS(MULTiplexed Information and Computing System)操作系统的大而无当所产生的谐音字。

在1957 年10月,前苏联发射了第一枚人造卫星,此举让当时的美国总统艾森豪威尔决定投下巨额的经费用以支持及发展科学,美国高等研究计划署(ARPA,Advanced Research Projects Agency)便是在这个时空下设立了,该单位负责推动系统发展等相关计划,成为当时美国电子计算器发展的重要推手。

1960 年代是大型计算机的发展年代,当时的麻省理工学院因最先实现了兼容分时系统(CTSS, Compatible Time-Sharing System),在电子计算器领域享有相当崇高的地位。1963 年,麻省理工的里克莱德(J. C. R. Licklider, 1915~1990)推动了 MAC 计划,MAC 以 IBM 的大型计算机做为主体,连接了将近 160 台终端机,这些终端机就四散在学区以及教职员的家中,可以让 30 位使用者同时共享计算机资源。这项计划到了 1965 年便不堪负荷,于是麻省理工便决定开发更大型的分时计算机系统。新的计划便是 -- MULTICS。一个计算机史上最为庞大的分时计算机系统,企图连接 1000 部终端机,支持 300 位使用者同时上线的分时计算机系统。她面临的是,操作系统的分时观念还在各学术与研究机构探索成形中,计算机硬件亦需重新设计的双重挑战。

当时,麻省理工原本找IBM来配合这项计划,但IBM正忙着应付自己的问题而无意配合 MULTICS 计划。此时,通用电子公司(General Electric Company)也就是奇异公司正好在发展自己的大型主机,见机不可失,便极力邀请麻省理工参予她们的 GE 645 大型主机的规格制定。有了奇异热心主动的计算机硬件配合,麻省理工找上的不能贩售计算机却人才济济的贝尔电话实验室来负责承包软件工程。于是乎,MULTICS 的计划便在 1965 年由麻省理工学院、奇异公司及贝尔电话实验室这三个成员开始共同发展。

1969 年,MULTICS 计划在历经四年的奋战后,仍旧未达到原先规划设计的理想,贝尔电话实验室决定退出计划。功能未达原始设计理想的 MULTICS 还是安装在奇异公司的 GE 645 大型计算机上供麻省理工使用。奇异公司在该计划草草结束后不到一年便完全淡出大型计算机市场。日后,MULTICS 计划被嘲解为Many Unnecessarily Large Table In Core Simultaneously。

农夫我个人认为, MULTICS 计划诞生在大型计算机将开始鼎沸的 1965 年,夭折于大型计算机最为辉煌的 1969 年。她如果适时在 1960 年代末期成功的话,绝对可以助长当时已经普遍被计算机权威人士视为理想的『计算机公用事业』,至少可以让大型计算机的发展与资源集中的应用模式就不至于会在 1970 年代初期就迅速萎缩。因为 MULTICS 计划如果成功,至少能让当时的大型计算机的应用规模大上 10 倍左右。然而,MULTICS 计划失败了。她严重地打击了当时依赖大型计算机主机的计算机公用事业业者在发展上的信心。更由于没有相似的计划后继进行,使得集中式的大型计算机主机没有明显的使用效能提升,而加速催化计算器工业的转变,以寻找新的道路。另一方面,MULTICS 计划失败的经验亦让当时参与该计划的软件工程师们得到相当宝贵的经验与正面的影响。

几年后,就在 AT&T,MULTICS 计划这个不同凡响的失败换来的一个不同凡响的成功。一个戏谑她的名字诞生了 .... UNIX。

一个游戏的开始

1969 年贝尔实验室的计算器科学研究中心(Computing Science Research Center)成员退出 MULTICS 计划的同时,贝尔实验室本身其实也没有一套完善便利的交谈式计算器服务环境。在其中不少工程师们也正为了改善程序设计环境努力着, Ken Thompson、Dennis Ritchie 和其同事们在当时草拟一个新的档案系统架构,这个档案系统也就是早期的 UNIX 操作系统的档案系统的前身。当时的 Ken Thompson 忙着使用 Fortran 语言将原本在 Multics 系统中开发的game 叫 "Space Travel"(太空旅游)转移到 GECOS System 上开发。当时 GECOS System 大型计算机的 CPU Time 相当昂贵(一秒要 75 块美金),同时控制 "spaceship"(宇宙飞船)的效果不甚理想,于是 Ken Thompson 不得不寻找替代的开发环境。Thompson 看上了一台很少被人使用的 Digital Equipment Corporation PDP-7 迷你计算机,当时 PDP-7 使用的是 Graphic-II 显示器,具有不错的图形处理能力。Brian kernighan于是 Ken Thompson 便与 Dennis Ritchie 连手将程序设计转移到 PDP-7 型计算机上。Ken Thompson 在移转工作环境的同时为了得到较好的发展环境,便与Dennis Ritchie 共同动手设计一套包含 File System、Process Subsystem及一小组 Utility 的操作系统,当时这套系统仅能支持 2 个使用者使用。由于贝尔实验室对于 MULTICS 计划失败的阴霾还未消散, Brian Kernighan 这位仁兄开玩笑地戏称这套新的操作系统为 UNiplexed Information and Computing System,缩写为 UNICS,之后大家取谐音便叫她为 "UNIX",没想到这个开玩笑的名字会被人叫到今天。

初期的自由发展

事实上该套 "UNIX" 系统在当时仅是私下的被使用,也并没有得到多大的重视,一直到 1971 年的一个正式的计划,UNIX才正式被搬上台面。

  PDP-11/201970 年,当时贝尔实验室的专利部门(Patent department)缺乏一套文书处理系统,为了设计开发的需要,于是买了一台 PDP-11 计算机。当时 PDP-11 计算机的交机过程并不顺利,处理器先到,硬盘则多等了好几个月。当 PDP-11 一切准备妥当后,他们便将 UNIX 移植到拥有 512K bytes 硬盘的PDP-11/20 型计算机上,并在此系统之下开发了一套文书处理工具。而这套工具便是后来 nroff / troff 的前身。那时的 UNIX 提供 16K bytes 给系统、8K bytes 给使用程序,档案最大的极限是 64K bytes。而此套含有文书处理工具的系统,也正式获得贝尔实验室的专利部门采用,系统名称并被编为 "First Edition"。在 UNIX 移植成功后 Thompson 用 B 语言为它添加了 Fortran Compiler,但因为 B 语言属于一种解译语言(interpretive language),执行成效并不是很好,于是 Ritchie 又将它 -- Compiler 发展成可产生机器码、允许定义数据形态及结构, Ritchie 称它为 C 语言。1973 年并以 C 语言改写全部UNIX 原始程序,UNIX 于是首度出现正式版本--V5 (第五版)。

此时的 UNIX 慢慢地在贝尔实验室内部蔓延开来,装机数也变成了 25 部之多。由于当时的贝尔实验室实际上是掌控在美国电信电话公司(AT&T)及其子公司西 方电器公司的手上,实验室主要是负责研究改进西方电器公司制造的和美国电信 电话公司在贝尔系统中使用的电信设备。同时根据军方合同,从事与国防有关的 研究与改进的工作。而 AT&T 本身由于有反托拉斯法的限制并不能从事于任何有 关计算机方面的销售,所以 AT&T 的主管阶层们对于当时 UNIX 的发展并没有太 多的支持,因而当时贝尔实验室内部对于 UNIX 的发展并不是相当在意也无意于 将之推广。不过为了应付实验室内各部门日益增加的 UNIX 使用者与相关技术支 持需求,还是成立了 UNIX System Group(简称 USG)。但该组织也仅只是 提供技术上的支持,并未赋予继续发展的任务。所以当时的 UNIX 发展,全靠 AT&T 的工程师们的努力。这段期间 UNIX 的发展完全没有组织及系统性可言,而玩家尽是一些工程师们,于是乎种下了 UNIX 日后较难以被一般人所接受的命运。

走出贝尔实验室

1974 年 Thompson 与 Ritchie 共同在 Communications of the ACM 发表 了一篇 UNIX 论文 "UNIX Time-Sharing System" 得到相当大的回响。 1975 年 UNIX 发表第六版(V6)﹐其提供的强大功能更胜过当时昂贵大计算机的操作 系统,其最大特点是以高级语言写成,仅需要做少部份程序的修改便可移植到不 同的计算机平台上。 UNIX V6 版本并附有完整的程序原始码在 1976 年正式从 贝尔实验室内部传播到各大学及研究机构,UC Berkeley 也就是依据这个版本开 始研究并加以发展,并在 1977 年发表 1 BSD(1st Berkeley Software Distribution)版本的 UNIX OS,其后续的发展更为 UNIX OS 贡献良多且影响 深远,此点稍后再为你说明。同年 UNIX 因它提供良好程序发展环境、网络传输 服务与及时服务 (Real-Time Services),而广得各电话公司采用。Interactive System Corporation 更因 Value Added Reseller (VAR) 运用 UNIX 来强化 办公室自动化环境,成为第一家应用 UNIX 操作系统的公司。此年 UNIX 亦被修改并第一次装到 Interdata 8/32 型计算机上。这也是 UNIX 操作系统首次安装在非 PDP 型的计算机上。自此 UNIX 系统开始被移植改装到各型微处理机及新计算机上。

一个稳定的基石

1978年UNIX发表对今日影响最重大的 UNIX 第七版(UNIX Time-Sharing System,Seventh Edition)也就是 V7。此版本包含 Fortran 77 compiler、Shell(只有Bourne Shell)、文件处理工具(nroff/troff、roff、 MS mocro等)、UNIX-to-UNIX-file-Copy(用来支持两台 UNIX 机器间的档 案传输)、数据处理工具(AWK、SED 等强悍的工具)、除错工具(ADB)、程 序发展工具(MAKE)、Lexical analyzer generator(LEX、YACC 等)、简 单的绘图工具、并支持 C 语言及 LINT verifier,主要执行于 PDP-11 及 Interdata 8/32 型计算机上。在当时那个年代来说其系统的架构与功能已经是 相当的完备的了。Bourne Shell 的原作者称她为 "improvement over all preceding and following Unices",在今日也有人称这个版本是 "last true Unix"。由此可见 V7 在 UNIX 发展里程上的扮演了相当重要的盘石角色。

在当时 DEC 公司推出了一款 32-bit supermini 主机 -- VAX,搭配的 VAX 的 操作系统叫做 VMS。这款迷你级计算机的硬件无可挑剔〈直到今日她的稳定度仍 是被诸多老一辈的系统管理者所赞许的〉,但 DEC 对 VMS 操作系统的支持性却 让贝尔实验室的工程师们宁愿使用 UNIX OS 。而这项工作则是由 John Reiser 和 Tom London 所共同完成。他们以 V7 为基础转移 UNIX OS 到 VAX 计算 机上使用。这个版本被称为 UNIX V32。同时为了转移的方便性,他们把 32-bit 的 VAX 当成是大一点的 PDP-11(因为 DEC 的 PDF-11 型计算机是 16-bit), 同时为了执行的效率,V32 放弃使用 VAX 硬件提供的一项 paging 功能(DEC 的 VMS OS 有支持 paging 功能,也由于 V32 舍弃这项功能,所以 V32 没有 虚拟内存的功能)。即使是如此,V32 支持的地址已高达 4Gb。就这样没有支持 paging 功能的 V32 开始被广泛的安装在 VAX 的机器上运作。DEC 则是在 1984 年左右推出来自己的 UNIX OS,叫做 ULTRIX。

一个重要的延续及发展 -- BSD UNIX

时间回到 1973 年 11 月, Ken Thompson 和 Dennis Ritchie 在印第安纳 Purdue 大学的一场操作系统原理的座谈会。会场上、坐着一位柏克莱大学 (U.C. Berkeley)教授,名字叫 Bob Fabry。当天的 K&R 所发表的 UNIX 立 刻引发 Bob Fabry 的极度兴趣。当时的柏克莱还是处在使用大型计算机主机、批次执行程序的阶段,并没有像 UNIX 这样的交谈式作业环境。会后,他便决定将 UNIX 带回柏克莱。

于是柏克莱的计算器科学、数学与统计三个系所合买的一台 PDP-11/45,准备用 来迎接 UNIX。1974 年 1 月,Bell Labs 寄来了一卷 V4 的磁带,学生 Keith Standiford 便开始进行安装 V4 的工作。安装时 Standiford 碰到了问题,便转 向 Bell Labs 求援。人在新泽西州的 Thompson 便透过柏克莱这端速度只有 300-baud 的调制解调器在在线进行侦错。

在UNIX 的发展史上,这是 Bell Labs 与柏克莱的第一次接触。

完成除错后,V4 便顺利地在柏克莱这台新买的 PDP-11/45 计算机上工作了。当 时这台是三个系所合买的,计算器科学好不容易装上了 UNIX,却碰到数学与统计 系所要使用 DEC&#39;s RSTS system,所以在一阵协调后,UNIX 与 DEC&#39;s RSTS system 以 8:16 小时的比例分配,供三个系所轮流使用。一段时日后,具交谈 式功能的 UNIX 在效能上的表现得到绝多数学生们喜爱,纷纷将自己的计划转向 UNIX 的时段。而一天占了 16 个小时的批处理时段却乏人问津。

当时Eugene Wong与Michael Stonebraker 教授,看上了 UNIX 提供的便 利性,便打算将他们的 INGRES 数据库计划重原先批处理的计算机环境转移到 UNIX 系统上面。在 1974 年,他们为这执行计划添购了一台新的 PDP-11/40 计算机,上面安装了 V5。这个计划也就是柏克莱的第一个将作业环境转移到 UNIX 的案子。UNIX 作业环境的需求,在柏克莱迅速地成长。为了应付需求, Michael Stonebraker 与 Bob Fabry 教授决定再申请购买两台 PDP-11/45。 1975 年初,DEC 推出 PDP-11/70,价格差不多等于两台 PDP-11/45,但功能强过 PDP-11/45,所以他们便决定改购买一台 PDP-11/70。

这台机器引来了Ken Thompson、碰上 Bill Joy 以及日后产生了 1BSD。她就宛如是一块 UNIX 史上的地标,沿袭自 Bell Labs,竖立在柏克莱,承先启后并开创新局。农夫个人认为,她应该被供在博物馆。

当这台机器在 1975 年终运达柏克莱时;同一时间,Thompson 受邀回母校(柏 克莱)当客座教授,科目就是 UNIX。Thompson 在校期间与 Jeff Schriebman 和 Bob Kridle 一起动手将新版的 V6 安装在 PDP-11/70。

Bill Joy1975 年,一位密执安州大学的毕业生来到了柏克莱,他的名字就是 Bill Joy。当时 Joy 和同学 Chuck Haley (tar 就是他写的)喜欢一起泡在计算机房里 面,Thompson 也时常插上一脚。他们成功地改善了 Pascal 的解译与侦错的能 力,同时还提升了解译与执行的速度。另外换装上 ADM-3 的屏幕后,他们觉得 ed 文字编辑指令并不合用;于是根据另外一个相似的 em 指令,发展了自己的觉得满意的文字编辑工具,也就是指令 ex。

1976 年夏天,Thompson 结束了他的休假回到 Bell Labs。此时的 Joy 和 Haley 已经开始着手探索 UNIX kernel,甚至还做了一些修改。1977 年初, Joy 制作了一卷磁带,上头写着 "Berkeley Software Distribution.",这就是1BSD。其中包含新的 Pascal compiler 与 ex 编辑器。

次年,来了几台新屏幕 -- ADM-3a,这种屏幕支持光标地址显示,Joy 在这种屏 幕上完成了有人爱不释手;有人恨之入骨的文字编辑器 -- vi。接着不久,Joy 便 发现一个问题,老旧的屏幕装备,还是会被用在其它的计算机上。为了支持上的 方便,Joy 针对此现象设计了一个接口,用来管理、支持不同的屏幕装备。这个 接口就是现在的 termcap。1978 年中,包含了功能加强的 Pascal 与 vi 及 termcap 的 "Second Berkeley Software Distribution," 也就是 2BSD, 迅速的取代了原先版本。1979 年,至少有 75 部 PDP-11 的机器上安装 2BSD 在运作着。自此在 DEC PDP-11 系列上执行的 BSD 版本便一直以 2.xBSD 作 为识别。由于 PDP-11 计算机实在相当长寿,持续到今日农夫我仍然在网络上发 现过关于 PDP 计算机的网站。似乎到今日它们仍旧在某些地方默默地工作着。 2.xBSD 最近的一次改版是在 1987 年,使用 4.3 BSD 为主架构改写,版本定 为 2.10 BSD。 在 BSD UNIX 中登场的重要功能当中,有一个直到今日仍然叫人又爱又恨的 指令 - vi。我接触过不少学习 UNIX OS 的人,大部分的人对 vi 的使用与掌握都不算顺手,其中恨死这个指令的也大有人在,前些日子农夫我还看到某个网站公开讨论起 vi 是否阻碍了 UNIX 的发展?实在夸张了一点!

Bill Joy 多次公开地说,他要是知道 vi 会如此受"欢迎"的话,他宁愿当初没有写 vi 这只程序。不过 Bill Joy 也说过,当时他原本还想加入一项 Multiple Windows in vi 的功能,不过当他在写这部分程序的时候,磁带机坏了,所以 Bill 只好在没有备份的情况下继续工作,想不到"屋漏偏逢连夜雨",程序写到一半,他使用的硬盘也跟着挂了。在无可挽救又没有备份磁带的情况下,Bill 宣告放弃为 vi 增加 Multiple Windows 这项功能。事后 Bill 为前一版的 vi 写好使用说明后就继续作其它的事。所以 vi 就长成今天那付德性。农夫我认为这或许是福不是祸!搞不好当初要是连 Multiple Windows 这项功能一起发表的话,上头的图可能就是遗照了。

当时有位 Richard Fateman 教授,原先使用一台 PDP-10 上进行着他的 Macsyma 研究计划。但他需要更大的内存地址来执行程序,所以在 1978 年 初,他看上了当时迪吉多新发表的 VAX-11/780。好不容易,他联合了其它的部 门才凑足购买 VAX 的经费。刚开始时,机器原本安装的是 VMS 操作系统。不过 别的成员要执行 UNIX 操作系统,于是 Fateman 安装上了 V32。但问题来了, V32 并不支持虚拟内存,Fateman 便找上了 Domenico Ferrari 教授,希望他 与他的研究小组能为 UNIX 加上这项功能。当时一位学生叫 Ozalp Babaoglu ,他想到了一些解决的方法似乎可行,但因为牵涉到 VAX 硬件与 UNIX kernel 的问题,于是他找上了 Joy 帮忙。就在只有一台 VAX 的状况下,他们努力奋战着。1979 年 1 月,在 VAX 上支持虚拟内存的 UNIX 版本终于诞生,V32 从此走入历史。紧接着 Peter Kessler 与 Marshall Kirk McKusick 为他加上了Pascal;Joy 则动手将 2BSD 上的 ex、vi、C shell 等工具转移了过来。这个版本就是 3BSD。一个首次支持虚拟内存、demand paging 和 page replacement 的 UNIX OS。

UNIX 与 DARPA 交会

1970 年代末,美国国防部先进研究计划机构(Defense Advanced Research Projects Agency -- 简称 DARPA)正在为 AI(Artificial Intelligence), VLSI及计算器视觉等研究(vision research)找寻一个可共通作业的计算机环境。硬件方面的首选是迪吉多的 VAX 主机。配合的操作系统是 VMS。这样的组合因拥有相当接近 DARPA 需求的功能被列入优先的考量,但在 DARPA 与 DEC 商谈对于 VMS 的支持事宜之后,DARPA 并没有得到满意的答案。这迫使他们考虑朝向UNIX 发展。但当时 UNIX OS(指的就是32V) 搭配 VAX,最大的缺憾就是没有支持虚拟内存;但此时已经有人克服了。

当时,Bob Fabry 教授写了一份建议书给 DARPA,建议他们以柏克莱支持虚拟内存的 3BSD 为基础,发展成为计划所需。这份企划书引起了 DARPA 的高度兴趣。随后 3BSD 也实际获得了 DARPA 相关计划成员们的良好风评,也因此最后柏克莱大学打败了卡奈基梅隆大学与 BBN(Bolt Baranek & Newman, Inc.),让 Bob Fabry 成功地获得了 DARPA 的资助合约。这份合约开始于 1980 年 4 月,为期 18 月。此后的 DARPA 便以 UNIX OS 为标准操作系统。Bob Fabry教授在取得 DARPA 合约后,依约成立了一个支持机构,也就是 Computer Systems Research Group 简称 CSRG。Bob Fabry 找上了 Bill Joy 来负责软件开发。Joy 迅速地以先前的 3BSD 为基础,整合新的功能。如 Job Control(作者是 Jim Kulp)、auto reboot、1K block file system。同时也整合入Pascal compiler、Franz Lisp system、enhanced mail handling system。这就是在 1980 年所发表的 4BSD。没多久她便被安装在将近 500 台 VAX 上。

DARPA 采用了这个版本作为当时 DARPA 的标准 UNIX 操作系统。

树大招风,当时,有位在 Stanford Research Institute 的仁兄叫 David Kashtan,写了一份关于 VMS 与 BSD UNIX 在 VAX 上的执行效率评估。该份报告指出 BSD UNIX 在效率上不如 VMS 来的好。Joy 知道这件事之后,花了不到一个星期的时间,重新调整 UNIX kernel。然后也写了一份报告,证明他们的 BSD 在 VAX 上要比 VMS 优越多多。1981 年 6 月,这个 Joy 调整过的系统,加上了 Robert Elz 写的 auto configuration,以 4.1BSD 的版本发表了。

当时的 DARPA 对柏克莱 4.1BSD 的表现相当满意,于是续签了两年的新约,金额更是先前合约的 5 倍。其中有一半的金额用在资助柏克莱继续发展 BSD UNIX 。钱多的相对代价就是要求高。当时,DARPA 对 UNIX 的期望开出了明确的目标;更迅速、更有效率的档案系统、支持程序可执行地址达 multi-gigabyte、提供弹性的解译沟通能力、具整合支持网络能力。在此同时,为了达到计划的目标,DARPA 成立的一个指导委员会;主要的成员有柏克莱的 Bob Fabry, Bill Joy, Sam Leffler、BBN 公司的 Alan Nemeth and Rob Gurwitz、贝尔实验室的 Dennis Ritchie、史丹佛大学的 Keith Lantz、卡内基.梅伦大学 Rick Rashid、麻省理工学院 Bert Halstead、信息科学协会 Dan Lynch、DARPA 的 Duane Adams and Bob Baker 以及加州.洛杉矶大学的 Jerry Popek。

不久,Joy 便开始整合早先 BBN 的 Rob Gurwitz 所发表的 TCP/IP protocols,不过他对 BBN 这些程序的执行效率并不满意,于是 Joy 与 Sam Leffler 重新写的一版自己的程序。另外,并加入了一些支持网络的工具 rcp, rsh, rlogin, rwho。他们称她为 4.1aBSD,这个版本并没有正式发表,在 1982年 4 月开始供内部使用。虽是如此,在 4.2BSD 未正式发表之前,她还是繁殖的到处都是。6 月,4.1aBSD kernel 加上了新完成的档案系统,版本更新为 4.1bBSD。

rcp, rsh, rlogin, rwho 这群指令。因安全机制上的理由,逐渐被另一群新的指令群所取代,新的指令群叫 SSH (Secure Shell)。SHH 相关网址(http://www.ssh.org)。

1982 年的春季末,已厌倦了在柏克莱环境的 Bill Joy ,答应受邀加入当年刚创办的 Sun Microsystems, Inc.,成为 SUN 的第四号创办人。那年的整个夏季 他就在两地奔走。之后他对修改中的弹性解译沟通机制及改写 UNIX kernel 到一个段落之后,由 Leffler 接手了他的工作。由于合约期限的因素,Leffler 在 1983 年 4 月发表了 4.1cBSD ,提供给参予 DARPA 各项相关计划的成员试用。6月,DARPA 的指导委员会第二次会议招开,验收与检讨最新版的 BSD 成果。继续整合 UNIX 系统的 Leffler,在 1983 年 8 月,发表了 4.2BSD。她达到了 DARPA 的预定的需求;足以应付 CAD/CAM 影像处理与 AI 研究的高速的档案系统及扩展强化的虚拟内存功能;提供能分散处理的解译沟通机制;支持56-Kbit 的 ARPA Internet 网络连结,以及 10-Mbit/s Ethernet 的局域网络;还有经过重组架构已模块化的 kernel code ,提供更有效率的计算机平台移植。

SUN 以生产 RISC 架构的工作站计算机为主,使用的正是以 BSD 为基础所的UNIX OS。在当时以不逊色于大型计算机的多人多任务、具网络沟通功能的UNIX OS、加上价格低廉的硬件(相对于 mini 级计算机而言),广获得工程界的青睐,而 mini 级大计算机的命运自此注定开始逐渐式微。计算机软件的应用因为有了网络于是也开始朝向 Client-Server 的架构发展。

1982 年,SUN 有了自己的操作系统 -- SunOS 1.0 -- 承袭自 4.1BSD。一直到 1990 年 11 月,发表 SunOS 4.1.1 版同时冠上 Solaris 1.0 时,SUN才算开始向 System V 版本靠拢。SunOS 4.1.1 可算是以 BSD 为主体再附加上 System V 工具的 UNIX 混血儿。但这其实是个商业考量的过渡性做法(后文会加以说明)。而 SunOS 4.1.x 版的字眼也仅延续到 1994 年的 SunOS 4.1.4 为止,她后继的版本是 Solaris 1.3。真正延续到今日的 Solaris 版本,则是始于 1992 年 7 月的 Solaris 2.0(SUN OS 5.0)。

在商业有所成就的 SUN Microsystems 对 UNIX OS 的发展倒也做了些重大贡献;如 1984 年发表的 NFS(Network File System)与其后在 1986 年发表的 PC-NFS。

商业化的不平坦历程 -- UNIX 版本的战争

UNIX 商业化实质上即意味着将产生各种独立化的 UNIX 版本,这点大概是最显而易见的事实。如果以商品要具备独特性与独占性的利益来做考量的话,其实一点也不意外。因此 UNIX 开始衍生的相当多的版本。这种现象,对使用者以开发应用程序的厂商而言,已经造成了某成程度上困惑。然而,一种无所适从的无力感其实才刚开始。

1984 年1月1日, AT&T 这个拥有 1495 亿美元资产、1,009,000 位员工的庞大巨兽,终于被格林法官 (Harold H. Greene) 以反托拉斯法 (antitrust) 强制拆解成七家 RBOCs (Regional Bell Operating Companies) 。AT&T 也因而在一夕间解体成为区域性网络公司,从此失去了长途电话的垄断性地位。这种时空的转变让 AT&T 对 UNIX 的态度有了 180 度的转变(其实,农夫我指的是收费的态度)。

先前已经提过 70 年代初期的 AT&T,已经在长途电话市场上占有绝对垄断的优势,因而被美国政府的限制不得涉足与从事计算机与其它行业,也正因而造就了 UNIX 发展初期的自由开放。直到 1979 年,AT&T 才宣布要将 UNIX 商业化的计划。1981 年 11 月,AT&T 属下的 USG 发表了 System III。次年又更新为System IV。稍后于 1983 年,AT&T 将 CRG, USG 合并成立了 UNIX System Development Lab. 一般简称为 USL,从其名称就不难清楚她将要扮演的角色。该年 System V 上市了。此时 AT&T 发觉每次版本更新都得花不少宣传费,实在不划算,所以决定在 System V 以后,名字就不再做变动了。1984年,System V Release 2 发表,简称为 SVR2。在这个版本中,才终于看到来自 BSD 版本的 Virtual memory 功能,农夫我不得不惊叹 AT&T 的稳健作风。SVR3 则是到了 1986 年才发表,随后 1987 年又发表了 SVR3.2。

1987 年,在工作站市场上已占有一席之地的 SUN,找上了 AT&T,打算将 System V 与 BSD 这两大版本归为一统。1988 年初,双方更签订了合作合约,AT&T 取得 SUN 的一席董事,同时亦有权买下 SUN 百分之二十的股份。这项合作计划,原本有机会整合当时版本纷乱的 UNIX OS。但那是理想。实际上这个计划反而让 UNIX 族群里的其它成员恐慌万分,特别是 IBM、DEC、HP 这几个产业龙头。为了抵制这项行动,他们组织了一个反对联盟。因此「开放软件基金会」也就是 Open Software Foundation 简称 OSF 在 1988 年正式诞生;成员除了前面的三巨头外,尚有多达三十几家计算机硬件制造厂商与系统咨询顾问公司,也相继以行动投入到此反对的行列中。然而 AT&T 与 SUN 也不示弱地组织了 UNIX International,也就是 UNIX 国际公司,成员数量虽然不比 OSF 阵营来的多,但如果她是 Intel、Toshiba、Unisys、Motorola、Fujitsu,这几个大块头,那也是很够看头的。

企业自身的利益在现实世界里始终是以个体的考量为优先,所以这两大阵营始终没能再达成任何共识,就连当时所制定的 UNIX 统一标准规格,严格来说也从不曾被实现过。这种企业利益上的冲突与矛盾其实也存在于同一个阵营中不同的成员之间。两大阵营对峙,可以说是 UNIX 有史以来最重大的产业冲突事件。由于商业利益的政治考量大过技术问题的考量,也因此奠定了 UNIX 将继续分裂下去的命运。 AT&T 在 1989 年发表了 SVR4,SUN 在日后也将她的 SunOS 4.1.1 开始冠上 Solaris 的字眼,以行动靠拢 SVR4。OSF 则是在 1990 年发表了OSF/1。UNIX 版本的问题因而更加混乱了。但有趣且可笑的是,开放系统 -- Open System,这个双方都标榜的理念与观念却因此在计算机产业界引起了回
响,这点倒是原先所始料未及的。

不久 AT&T 撤销了对 SUN 的投资,同一个阵营的成员彼此也因而劳燕分飞。USL 在 1991 年正式转变了一家独立的商业公司。但 UNIX 在商业市场上的价值却出现了变化...

让UNIX 自由 -- Networking Release 2

自从UNIX 走出贝尔实验室后,研究机构与学术界就扮演了继承与发展的双重角色。在 1979 到 1984 年这段期间,UNIX 的拥有者 AT&T,对于学术界的授权政策尚可用『大方』来形容;同时也对学术界做某种程度的资助与合作。当时的学术界,得助于 AT&T 的大方授权与分享程序原始码,研习 UNIX 这个分时操作系统开始在学术界蔚为一股风气,甚至可以说是一种潮流或一种流行。其中,像柏克莱 BSD 对 UNIX 的贡献,就是一个公开的事实。但早期的 BSD 使用者,是必需向 AT&T 支付授权金的。这点,从产业界资助学术界的角度来看是一点也不值得惊讶的。因为资金的援助为了就是取得其成果。所以当时基于 AT&T 原始码所发展的成果,均归属 AT&T 所有。也因而 AT&T 掌控了 UNIX 的所有权。到了 1984 年以后,AT&T 开始更积极地保护 UNIX 的原始码;AT&T 甚至还要求各大学的使用人员签订保密条约,想藉此防堵 UNIX 的原始码从学术单位流出,以影响到商业利益。

在DARPA 资助柏克莱从事 BSD OS 发展的过程中,诞生了 TCP/IP 这项广泛影响现今计算机与因特网的通讯协议。由于 DARPA 对于资助开发的软件项目有明文规定接受资助者必须无条件地释出程序的原始码,所以 TCP/IP 的原始码与程序的版权并不属于 AT&T 所有。这点在现今看来其意义是不凡的。也正因为有此一条件,柏克莱的 CSRG(Computer System Research Group)因应 BSD Vendors 需求,在 1989 年 6 月发表了 Networking Release 1,她包含了 TCP/IP source code 以及一些工具,提供给当时正开始起步发展的个人计算机制造业者使用。Networking Release 1 授权收费仅 1000 美元,而且不需要 AT&T 的商业授权,取而代之的是柏克莱大学的开放式授权。

农夫我看柏克莱授权方式,几乎可以说是一种良心式授权方式,在实质的运用上她完全没有限制。她允许原始码或执行档在任何情况下修改并且允许将修改后的程序从事商业行为而无须任何回馈,当然也没有绝对要求开发者必须要释出原始码。如果你改都不改地加以贩售,她也没有意见。但有一点不可违反的限制,就是必须在衍生物的版权声明上提到柏克莱的贡献。这种做法在日后,也没有多少改变,而这样的授权方式也成为了柏克莱的授权精神。

Keith Bostic由于 Networking Release 1 所得到的响应实在远超过 CSRG 成员的预估。这个不算差的成果,让柏克莱的 CSRG 觉得有必要释出更多属于 BSD 的程序原始码。于是激发 CSRG 的成员 Keith Bostic 开始组织志愿工作者从事一项就算不能够惊天也足以动地的程序写作计划。计划的主要目的在当时还真让人感到有点"乌托邦"。农夫我个人喜欢戏称她为『解放 UNIX 计划』。

Marshall Kirk McKusick这项计划大体上分成两个部分,操作系统工具(Utility)与核心(kernel)。而且参与人员必须在完全没有参考 AT&T UNIX source code 的情况下进行撰写程序的工作。因为只有在这种条件下,写出来的程序代码,才能摆脱 AT&T 的著作权束缚。当然这也绝对不是一件容易的事。Keith Bostic 四处奔走,组织了超过四百名热心的软件工程师,经过了长达十八个月的奋战之后,操作系统主要的工具与链接库才算改写完成。Marshall Kirk McKusick 负责改写当时的核心程序。但系统核心的部分,由于长期以来柏克莱与 AT&T 一直就彼此分享 UNIX 原始码,所以各自所加上去的程序代码早已混杂难分了。为了彻底的厘清双方各自撰写的部分,他们下决心进行逐行比对。首先花了好几个月的时间,将核心程序每一行每一个档案都建立转换比对的数据库。然后接着进行移除来自 AT&T 32V 的程序代码并改写她们。即使是如此,仍旧有 6 只程序让他们束手无策,因而无法将核心程序彻底完整地改写。最后,他们还是决定将他们所做的所有成果发表。授权的方式沿用 Networking Release 1 的授权方式,授权的磁带依旧是 1000 美金。这个版本就是 Networking Release 2,也有人称她为 4.3BSD NET/2。发表的时间在 1991 年 6 月。虽然这是个不完整的操作系统。但,在今日看来,却有着划时代的意义 -- UNIX OS 自由了。

谁是"老大哥" -- 侵权诉讼

AT&T 的 USL 在 1991 年正式转变了一家公司。当然,这意味着她将更重视UNIX 在商业上的利益。当时的 UNIX OS 早以称霸高阶的计算机市场;从 Cray 超级计算机、IBM 的大型计算机主机、迷你级计算机到工作站,均是 UNIX 的天下(这一点,直到现在21世纪,仍旧没有多大的改变)。即使在 80 年代中期后开始迅速发展的个人计算机,虽然当时被戏称为是玩具计算机,但也仍旧有像XENIX[注1], Interactive UNIX[注2] 等几种向 AT&T 缴过税的商业化版本。UNIX 简直就是 AT&T 的一棵摇钱树。

但这一切在 Networking Release 2(以后简写为 Net/2)出现之后,起了变化!

首先,一位 i386 处理器的玩家名叫 Bill Jolitz,在拿到 Net/2 之后,很快地就将 Net/2 kernel 缺少的程序补齐了。BSD kernel 这时可算是大功告成了。当时 Bill Jolitz 将他们放在因特网与其它人共享他的原始码,并且得到了不少正面的响应。由于这个版本是使用在 i386 微处理器的个人计算机上,所以就命名为386BSD,在 1992 年 2 月正式发表。这该算是 BSD 首度功能完整且版权独立的版本。Bill Jolitz 是当时唯一的 kernel 维护者。在他离开这个计划之后,继起的 BSD 玩家们延续了这个版本,日后衍生了 FreeBSD,然后又从其中分支出裂 NetBSD 版本。

另一个将 Net/2 完整化的是一家叫 Berkeley Software Design, Incorporated 的公司,简称 BSDI[注3]。由于 Net/2 的版权声明中,宣称其源文件的合法性,并且允许使用者,从事衍生物的商业行为,所以 BSDI 将他们修改后的系统命名为 BSD/386。他们并将成果打包,刊登广告以 995 美金的售价贩售 BSD/386,而且含原始码,而且还提供免费服务电话的咨询,电号号码是"1-800-ITS-Unix"。时间大约是在 1992 年 1 月。当时,USL 的 System V 含 source code 的价格大约是 BSD/386 价格的一百倍左右。这可惊动了老大哥 AT&T。并且正式地书面严重警告 BSDI 违反的注册商标法(电话号码里有 Unix 的字眼),并公开宣称 AT&T 拥有 UNIX 的注册商标。BSDI 再次刊登广告公开反击 AT&T,声明她的商业行为完全合法。果不期然, BSDI 的博命演出让双方手牵手走上法庭。

AT&T 的 USL 控告 BSDI 剽窃他的 UNIX 原始码,要求法官还他公道。在听证会上,BSDI 祭出早已准备好的法宝;自己在无任何 AT&T source code 的条件下写出的合法档案,以及来自于 BSD 授权的 Net/2 source code。前面的证据足以让 BSDI 立于不败之地,后者让 BSDI 置身在暴风圈外。BSDI 的辨证获得了法官的采信。但 At&T 岂会就此罢手,他们将焦点转移到 Net/2 的 BSD 授权上面,并且重新提出控诉,被告的对象变成了 BSDI 与柏克莱大学;同时 AT&T 还申请法庭禁止 BSDI 一切的 BSD/386 销售行为。就这样,柏克莱大学也对号入座了。

农夫我认为,毕竟 AT&T 是营利企业,她得维护她的商业利益,这点是天经地义的事。虽然柏克莱大学与 AT&T 在 UNIX 发展上有着非比寻常的关系,但商业利益是现实的。企业资助学术界的研究计划,多半是基于商业上的考量;我相信,学术界的少数高层在寻求奥援时不会不明白这一点,即使这有可能让大部分的学术人士无法接受或不愿接受。不管如何,这一记醒棍倒再次挑起了这一点事实。

成为被告的柏克莱大学,只好无奈地面对这场无情的商业诉讼。但他们也同样不甘示弱地对 AT&T 的 Systerm V 著作权提出质疑,因为在 AT&T 的 UNIX 授权声明中完全没有提及柏克莱的贡献。所以柏克莱反控 AT&T 违反 BSD 的授权条款。柏克莱的反击让战况越演越烈,诉讼案一路从 AT&T 的老家新泽西州的联邦法庭打到柏克莱大学的所在地加州法院,但依旧没有结果。

到了1993 年,官司还在进行中,但 AT&T 却已经打包 USL 准备以一亿美元的价格找寻买主了。最后 AT&T 将 USL 以八千万美元代价的卖给了 Novell。而新买主也当仁不让地加入了这场混战。但却也因此,战况露出了一线平息的曙光。诉讼案在 1994 年 1 月宣告终结,以庭外和解收场。实际的协议内容仅有当事人知情。

如果从胜负的角度来看这场诉讼,或许柏克莱与 BSDI 是胜利的一方。但如果从 UNIX 发展的脚步来看这场诉讼,就可能根本没有任何一方是胜利者了。

事件平息后的 1994 年 6 月,柏克莱的 CSRG 风光地发表了 BSD 4.4 Lite。在这个版本中,有 70 个档案引用的一份新修改的版权声明,阐述的 AT&T 与 BSD 双方的贡献,并明确地给予档案自由散播的权利。但不知为何,应该有能力完整发表的 BSD 4.4 Lite 还是缺少了三的档案。当时,农夫我也很高兴地买了一本BSD4.4-Lite CD-ROM Companion,含一张光盘,现在拿在手上,看来总觉得有点呆。

掌握 UNIX source code 以及 UNIX 商标的 Novell,将 UNIX 商标交给 X/open 管理,自己则发展了一套命名为 UNIXWave 的操作系统。推出后市场的反应并不热络。不久,Novell 与 SCO 接头,在 SCO 保证继续支持 UNIXWare 的条件下,UNIX 在 1995 年二次易主,新主人是 SCO[注4]。

备注:
*1 Intel 在 1978 年发表 4.77 MHz 的 8086 微处理器。1980 年,Microsfot 便以 V7 为基础,发表了在微处理器(microprocessor-based computers)上执行的版本也就是 XENIX。到了 1982年,一家成立于 1979 年的软件公司 Santa Cruz Operation,成为微软的合作开发厂商。之后她这家公司便一直致力于这个领域里延续到今日,缩写就是今日的 SCO。

*2 Interactive IS/1 (以 V6 为主体)。这个版本后来演化为比较让人熟知的名字 -- Interactive UNIX。后来因为 Sun Microsystems 致力发展 Solaris for X86,被财力雄厚的 Sun Microsystems 合并了,如今已经不见踪迹了。

*3 就在我反复修改这段文稿的时候,BSDI 这家公司已经被 Wind River 合并了,改名为 iXsystems。2001/05/03

*4 2001 年 5 月 4 日,Caldera International, Inc. 正式并购了 SCO 的服务器软件部及SCO专业服务部这两个部门,新的控股公司名为 Caldera, Inc

GNU 计划 -- 开启了新大道

在1983 年 9 月 27 日,麻省理工学院人工智能实验室(MIT Artificial Intelligence Lab)的 Richard M. Stallman (以下简称为 RMS),在 net.unix-wizards 以及 net.usoft 的 newsgroups 贴上了一份标题为 "new UNIX implementation" 的讯息。这就是如今广为人知的 GNU 计划的开始。在那则被视为「GNU 宣言」草稿的讯息中,RMS 阐述个人的理念与计划的目的 -- 完成一个命名为 GNU 的 "Free UNIX" 操作系统,希望藉此寻唤理念想同者共襄盛举。

『如果我喜欢一个程序的话,那我就应该分享给其它喜欢这个程序的人』,这是 RMS 的座右铭。此点也似乎正是促使其决心运作 GNU 计划的原动力。当时的 RMS 是想写出一套免费的操作系统。能够让每个人如空气般地自由的取得与使用。选择“UNIX 兼容”为设计的主要原因是;RMS 表明,UNIX 并非他个人理想中的操作系统;他仅阅读一些相关数据,但未曾使用过 (MIT 使用操作系统是"ITS--Incompatible Timesharing System");但他认为 UNIX 操作系统具有优良的本质特性。他相信如果 GUN 与 UNIX 兼容将更容易令人接受。所以 RMS 承袭 MIT 用递归缩写字命名的传统为 GNU 释译界定 Gnu is Not Unix。

1984 年 1 月,RMS 为了展开他的理想而决心离开已经待了十几年的 MIT AI Lab.。当他向他老板 Patrick Winston 辞职时,Winston 试图挽留地说:「你还是要辞职?」。RMS 不为所动的回答:「是」。Winston 显然得到预料中的答案,于是接着说出了思绪里关怀:「你想要保留你的钥匙吗?」。于是 RMS 就从此开始专心地"失业"在他的老东家。一个人窝在他原来的旧办公室中,规划着如何开始他的 GNU 计划。但想开发一套新的 UNIX 兼容的操作系统,即使是财力、人力资源雄厚的顶级计算机公司,也绝对不是一件说想做就能够做到的事。当拟妥他的「GNU 宣言」之后,他正式向全世界呼唤、表明其将所为。种子落地了。

GNU 计划的第一只程序要算是孤军奋战的 RMS 在 1984 年 9 月开始撰写的 Emacs 编辑器。1985 年初,Emacs 已进入可用的阶段。于是 RMS 将她放在 pre.ai.mit.edu 这台机器的 FTP server 上,免费地让 amonymous 的到访者自由下载使用。不久后,Emacs 强捍的功能引发了一些玩家们的注意,由于附上了 source code,玩家们能自己动手为它添加新的功能或除错,很快地,Emacs 获得了相当热烈的回响。随着名声渐播,开始有人相继地加入 GNU 计划的程序写作阵营。"此道不孤"让 RMS 倍感振奋与喜悦。

当时的因特网并未十分普及。所以有不少人虽然对 Emacs 程序有兴趣,却没办法经由 FTP 的管道取得,因而有人透过其它管道向 RMS 询问能如何取得时,这可让当时处在失业状态的 RMS 看到能够支持他继续奋战下去的资金来源--贩售"自由软件"。

一个人、一个独立的个人,要想在现实中实行自己的理念,最先得接受"现实"。唯有接收它是事实,实行理念的道路,才获得比较稳固的起点与开始。  -- 网络农夫如是说。

想着、写着,脑中突然掠过一丝感受(所以顺便记录在这个地方)。不管如何, RMS 真的开始以一卷磁带 150 块美金的代价,服务有需要的人。也因为基于这个开始与基础,RMS 当年便创立了自由软件基金会 -- Free Software Foundation (以后简称为FSF)。这对 GNU 计划而言,意味着它已跨越个人化理念的构思阶段,并进入了有群体组织化的运作阶段。同时,RMS 也制定出了属于 GNU 计划的软件版权。RMS 使用 "copyleft" 用来形容她,其实就是与著作版权(copyright) "对立"之意。这也就是 GPL -- General Purpose License (通用公共授权)。GNU 计划的种子,就这样生根发芽了。

从贩卖 GNU 自由软件扩展到其它的相关软件与参考手册,提供软件技术支持,并接受计算机器材与资金的捐助(捐助者依法享有一定额度的减税),为企业代训软件人才。FSF 努力地开辟财源却仍旧是运作资金捉襟见肘。RMS 本人并不支薪。而 FSF 聘请软件工程师的待遇,也仅是软件业界薪资水平的一半。但这绝不表示 GNU 计划的软件水准是半桶水。GCC 编译器是 GNU 计划在 1987 年 3 月开始发表的免费编译器,当时的版本是 0.9 测试版。如今最新的版本则是 3.0。这个编译器可以说是今日自由软件写作的基石。GCC 所解译的机器码,其可靠度绝对不逊于商业化的编译器产品,甚至可以说是优越过商业编译器。

90 年代初,GNU 计划暨已完成了质量与数量均十分可观的系统工具。这些工具被广泛的使用在当时各种工作站的 UNIX 系统上。虽然已有如此的成果,但仍称不上是完整的操作系统。他们缺少一支属于自己的"核心程序(kernel)"。

UNIX 在 4.2BSD 之后,越写越大 kernel 开始带来一些不便与问题。因而当时便开始有另一个写作理念逐渐在发展--微核心(microkernel)理念。

1985 年,卡内基大学(Carnegie Mellon University 简称 CMU)暨以 4.3BSD 为发展基础,将之一拆为二,分成 micro kernel 与 single server 两个部分。该计划的名称为"Mach"。这个计划成了微核心发展的技术先河。GNU 原本有意直接采用 "Mach" 计划的成果。但无奈,这一等,从80年代中等到了90年代初,在几经商量之后,他们打算采用微核心的写法,成立自己的计划,名称叫"Hurd"。这项计划,如今仍在奋战中,虽然 microkernel 的做法让他们吃了不少苦头;但可喜的是,0.2, 0.3 测试版本已经发表。

直到 21 世纪的今日,RMS 依旧努力不懈地耕耘着他的梦土。尽管他本人认为还尚未完全地实现他的「GNU 宣言」;但他执着于理念的行动,已凝聚了相当数量的自由软件写作族群们,在这些人与群体的努力下,一条新的大道其实已经被开拓出来了,她通往一个新的世界。大道旁,枝叶已然繁茂的树荫下,可口果实一如礼物般地为所有的人成熟。人们称她 -- Linux。

新世代的焦点 -- Linux

1990 年代中期,因特网因出现 World Wide Web, HTML 这种新型态的应用,而开始迅速的延烧全世界。一夕间,架设因特网主机的需求激增。这时有一套可以免费取得,并且能让 x86 计算机升格成 UNIX 级主机的免费操作系统,开始了吸引全世界目光。在传媒与计算机工程师们的竞相走告下成为了这个新世代的焦点,这个新的名字就是 Linux。

Linus Benedict Torvalds当然,这套媒体吹捧的当红炸子鸡,可非一人之功,一夕即成的。Linux 是一套版权彻彻底底与 AT&T 无关的 UNIX-like OS。原始核心程序的创作者是芬兰籍的 Linus Benedict Torvalds(现今他仍旧是核心程序的维护者)。操作系统里大部分的系统工具,来自于 RMS 行之多年的 GNU 计划成果,以及其它的自由软件写作计划产生的软件,如 X Windows、KDE、Gnome 等窗口接口。由于构成操作系统的主要部分均奉行 GPL 版权,所以市面上有相当多样的安装套件,目前较广为人知的有 RedHat、Slackware、SuSE、Debian GNU/Linux...。也因此,这套操作系统,可说是包含了无数字自由软件写作者的共同心血。如此的一套操作系统其实也就是 RMS 多年来想要达成的宿愿 -- "Free UNIX"。所以,RMS 本人总认为该将名称改做"GNU/Linux"。因此,也有人用 GNU/Linux 来称呼这个操作系统。

Torvalds 打从十岁出头当他外公的"键盘手"开始,到了中学就已成了不折不扣的计算机迷。1990 年,当他就读赫尔辛基大学(University of Helsinki)信息系二年级,选修一门「C 语言与 UNIX 操作系统」的课程,因而疯狂地迷恋上了 UNIX 操作系统。那年正好赫尔辛基大学正好添购的一台 VAX,安装 Ultrix 操作系统。连接了 16 台终端机供授课师生使用。有所限制的计算机资源,对一位计算机迷来说是极痛苦忍受的。Torvalds 开始作梦想"搞"一套可以在自己计算机上跑的 UNIX。

1991年1月,Torvalds 利用 "学生贷款" 加上去年的 "耶诞红包",以分期付款方式买了一台 386 DX33 个人计算机(他的第三台计算机)。他选择安装的操作系统则是在学术界颇负盛名的 Minix[注5]。在几番奋战下,就绪运作的 Minix OS 功能性却多方面无法满足 Torvalds 的需求,因而激发了他重头来的欲念。于是 Torvalds 在他的 386 DX33 上逐步探索并撰写出他自己的核心程序。他网络上释放的第一个版本是 1991 年 9 月 17 日的 0.01 版。虽然她是个简陋的开始,但由于 Torvalds 本人持续维护与网友回馈贡献,原本一个人所撰写的核心程序竟在不知不觉中逐渐转化成 "虚拟团队" 的运作模式。

然而,一般计算机使用者,需要的是可安装运作的操作系统(农夫我习惯以"安装套件"称之),而非单一的操作系统核心。当时英国的曼彻斯特电算中心(Manchester Computer Center, 简称 MCC)便根据 0.12 版核心程序制作了一套名为 MCC Imterin 的安装套件。随后各地的安装套件有如雨后春笋般地出现;如美国德州 Dave Safford 的 TAMU(Texas A&M University)版、Martin Junius 的 MJ 版、Peter McDonald 的 SLS(Softlanding Linux Sustem)版等非商业安装套件的出现。在安装需求日增的情况下,Linux 安装套件创造出了一块新的需求市场。这一线商机,让非商业安装套件的也开始出现在商业市场上。Slackware 大概可算是最早出现的商业安装套件了。到如今,商业与非商业的安装套件则已多得数不清了。

随着使用人数激增,核心程序的版本与功能也开始加速演化,但仍不失于稳健。1994 年 3 月 13 日,核心程序 1.0 正式发表。其安装套件在功能上的整合已急起直追当时商业版的 UNIX OS。此时的 Linux OS 已拥有数十万名使用者。当时赫尔辛基大学还以此为由举办了一场名为"Linux 首度正式发表会"。就在芬兰电视台与众多传媒的郑重其事的报导下,Torvalds 成了芬兰人的自豪,Linux OS 宛如刚诞生的"超新星",闪闪发亮地展现在众人眼前。

早期的 Linux 核心程序曾被 Andrew Tanenbaum 指出,过度紧密地与 x86 处理器结合,所以他认为 Linux 核心程序将无法移植到别的处理器上。这点显然与 UNIX OS 的可移植性大不相同。当时的情况的确是如此,这或多或少与 Torvalds 本人受限于拥有的硬件资源有关。但当 Linux 的使用族群拓展开来之后,便开始有人主动地将她移植到不同的平台上。像 Dave Miller 即以不下于 Torvalds 狂热与学习精神将 Linux 成功地移植到 SUN 的 SPARC 工作站上。此外如 Amiga、Atari、PowerPc、MIPS R4000 也陆续见到 Linux 的身影。这些移植严格地从技术的角度来看,仅能说是"个案"。但这已激发 Torvalds 的兴趣。真正撼动 Linux 核心的移植是对 Alpha 处理器。

1994 年 5 月,在 DEC 使用者协会上,Digital 的工程师 John Hall(外号Maddog)碰上了 Torvalds,双方一见如故。Maddog 力劝 Torvalds 将 Linux 移植到 Alpha 芯片上,并主动提供了一台 Alpha 计算机供 Torvalds 研究使用。当年可说是全世界最快的 64-bits Alpha 芯片是 DEC 引以为豪的一项成就,其架构与功能均优越过同一时期的 Intel 32-bits 处理器。这种技术性的挑战吸引了 Torvalds 的投入。这项移植,但这对原先以 x86 微处理器为写作基础的 Linux 核心程序而言,实在不是一件小工程。在 Torvalds 与 DEC 相关人员的将近一年奋战后,Linux 核心程序脱胎换骨,成功地移植到 Alpha 处理器上(与 x86 处理器使用同一套程序代码)。1995 年 3 月,被戏谑是 Linux&#39;95 的1.2 版核心程序正式发表,支持 Intel x86、DEC Alpha、SUN SPARC、MIPS 等处理器。

1996 年6月,核心程序版本由 1.3 直接跃升为 2.0 版。Torvalds 本人正式钦定了一只"企鹅"作为 Linux 的标志。同时也开始支持对称式多重处理器(Symmetric Multi-Processing,简称 SMP)架构的计算机;而支持的处理器则又多了 Motorola 68k 和 PowerPc。在自由软件团体们的努力与计算机产业业界的支持投入之下,Linux 具备的功能逼近商业版 UNIX OS。当然,Linux 要达到"成熟"与"稳定",实际上还有好长的一段路要走。

时至今日,散播在全球各地的 Linux 虚拟发展团体,仍旧持续地发展中。能维持到什么时候?这在将来的历史自有答案。但至少在现今,一个 RMS 奋斗的目标 -- 可自由分享程序代码的操作系统,已可贵地呈现在我们的眼前。

备注:
*5 Minix 是 Andrew Tanenbaum 教授为教学目的而撰写的操作系统。在教育界可算是一套学习 UNIX 基础的好范本。

新文明世紀 自由共享

到此,这一段关于 UNIX 发展的文字,已从过去的历史当中走回到了今日 ... 21世纪的今日。本文也接近尾声了。请诸位原谅农夫将以极为自身的历史感受,来作为本文的结语。

阅读与探究历史,是农夫个人在年轻时即有的一点小癖好。通常我无法忍受对自己喜好事物的缘由一无所知。所以我会想办法去探究她由谁所创、因何而生与发展的沿革。也正因为如此,我才会为 UNIX 这个当初我没能在英文字典上找的怪字,写了这么一篇文字。

然而在 UNIX 的发展过程当中,我惊讶地发现了一项有别于我探索 20 世纪历史的东西。我相信诸君应该清楚,20 世纪是人类文明史上最为血腥残暴的一段岁月。在其间,多数民族的上个世代所遭逢的苦难,都是空前的。哲学家柏林(Isaiah Berlin)回顾 20 世纪的感受,说了以下这样的一段话。

「我的一生--我一定得这么说一句--经历了二十世纪,却不曾遭逢个人苦难。然而在我的记忆之中,它却是西方史上最可怕的一个世纪。」

的确,每当我阅读 20 世纪的相关史料,我就更能加倍地感受到这份莫名的幸运。我生长在台湾,这块回顾其历史仅能以"悲土"称之的岛上,她的苦难直至今日亦尚未完全结束。尽管多数年轻的一代已然淡忘,来自何方,归往何处。身为一个中国人,站立在这块似乎仍将被同胞武力相向的孤岛上....我已不清楚历史伤口会因得到同胞的爱而痊愈,还是再次因人类残暴掠夺的天性而迸裂.........抱歉,离题了.

我想说的是,在 20 世纪未的因特网时代中,我感受到了令人喜悦地,根源于心、跨越既有疆界藩篱的自由共享文明。这相较于 20 世纪初将"战争"视作为文明象征的人类而言,实属无价可贵的进展。即使这文明仍仅是刚播下的种子。但我相信,她将如贝聿铭所言:

「你永无法明确知道你已播种的东西何时可以收割;或许只有一次收成,或许可重复收成。你也许遗忘曾播种了些什么,一种经验,一种感受,与某人的关系,抑或一种哲学及一项传统。然后,忽然间就开花了,被全然不同的环境所唤醒。这种盛开可以冲破藩篱及整个时代。」

多希望亲眼看到,几个世代后的某日,人类彼此掠夺的行为如天花一般地在人类社会中绝迹;而,共享已成为人类整体奉行的道德公理。如果这样的一个社会是我们今日所企求的;那么,这个方向与希望,就值得你我花一生的精力去努力。当然,这仅只是一个个人的希望,我也清楚这世间并非如此美好。但,如果因假设一件事物不可能做到,而决定不去做;那是假设得到胜利,而非真实的事实。或许过去的历史,曾经证实正义、公理、平等与理想的胜利,不过是短暂的昙花一现;那又如何。只要我们不放弃希望,希望就有机会成为真实。今日,所有的美好均因此得来,明日也是。

这几年来,我已看到不少因特网上诸君们的努力。我也相信这崭新文明的种子,有朝一日将展现出令人赞叹、愉悦的美景。未来存在我们尚未发现的国度。我相信,我们能发现未曾走过的通道,打开不曾打开的门,进入玫瑰园中.....那会是一个崭新的文明。

处理器发展史 不可不知的故事

  如果要列举上个世纪涌现的、对今天人们的工作和生活产生了重大影响的技术创新,相信PC(个人电脑)一定会榜上有名,甚至还会名列前茅。事实上,随着互联网的普及,PC已经成为如今全球至少10亿多民众在日常生活中接触最多、依赖程度最高的电器,他们已经无法想象没有PC和互联网的生活。而对于PC来说,它得以问世的最重要的前提条件就是CPU的发明,而且这么多年来,CPU也一直是PC中最重要的核心组件,人们同样难以想象,没有CPU的PC会是什么模样。

  谈到CPU的发明和数十年来它在技术上的进步,就不能不提及英特尔公司。网上有一篇点击率非常高的文章,介绍了PC发展史上的20位“英雄”人物,其中有4位就是来自英特尔公司,他们包括了英特尔创始人——罗伯特·诺伊斯、戈登·摩尔、安迪·葛洛夫,还有一位就是CPU的发明人,英特尔历史上首位院士——泰德·霍夫。正是从这4个人开始,在英特尔内部,在英特尔与其他厂商之间,围绕CPU的发明和推广,曾经发生了很多我们不可不知的故事。

  所有与CPU相关的故事,最初的起始时间点都是1969年的春天,那是英特尔公司成立后的第二个年头。当时全世界的计算器公司都在寻找能够为他们生产芯片的半导体企业,得益于罗伯特·诺伊斯和戈登·摩尔这两位科学家型创始人的声名远扬,一家名为Busicom的日本计算器公司找上门来,希望英特尔能为他们设计和制造计算器芯片。英特尔将这个项目交给了公司的核心员工泰德·霍夫。Busicom要求他设计12块功能各异的专用芯片,但霍夫并没有按照这个思路去做开发,因为这种想法无法有效降低这些芯片的成本,而且还非常复杂。他只开发了四种芯片——一个代号为4004的简单但拥有多种功能的4位逻辑芯片,两个存储器芯片(分别为RAM和ROM芯片),以及一个移位寄存器芯片,4004就成为了史上第一个CPU,它与另外三块芯片通过总线连接后,就构成了世界上第一台微型计算机——MCS-4。

  对于霍夫的发明,当时的英特尔高层并不是全票支持。当时英特尔的主营业务还是以DRAM为代表的半导体存储器,安迪·葛洛夫就对这个新产品很不感冒,他甚至还声称:“微处理器对我而言没有任何意义,我为存储器的产量而生,也会为其而死。”不过,在诺伊斯和摩尔等人的坚持下,英特尔还是在1971年10月推出了4004,市场的反应有些出乎英特尔的意料,当它在4004年广告中宣称这款产品将开创“集成电子——芯片上的微型可编程计算机的新纪元”后,有5000多人立刻写信与英特尔取得联系,希望获得更多有关4004的信息。这种受到业界热捧的现象很快让英特尔认识到了CPU的价值,为此它后来还从Busicom买回了CPU的所有专利,此举实际上为它自己开辟了后来最为重要的一条发展道路。