2007年5月23日星期三

[ZZ]linux下的proc文件系统解析

在追踪Larbin的config.h文件时,发现原来它是从configure中产生的:
configure文件中有如下语句:
if [ -e /proc/self/status ]; then
echo "#define HAS_PROC_SELF_STATUS" >> config.h

/proc/self/status是什么?于是搜到了下面这篇文章。

linux下的proc文件系统解析
proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过 proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。它的目录结构如下:

目录名称 目录内容
apm 高级电源管理信息
cmdline 内核命令行
Cpuinfo 关于Cpu信息
Devices 可以用到的设备(块设备/字符设备)
Dma 使用的DMA通道
Filesystems 支持的文件系统
Interrupts 中断的使用
Ioports I/O端口的使用
Kcore 内核核心印象
Kmsg 内核消息
Ksyms 内核符号表
Loadavg 负载均衡
Locks 内核锁
Meminfo 内存信息
Misc 杂项
Modules 加载模块列表
Mounts 加载的文件系统
Partitions 系统识别的分区表
Rtc 实时时钟
Slabinfo Slab池信息
Stat 全面统计状态表
Swaps 对换空间的利用情况
Version 内核版本
Uptime 系统正常运行时间

并不是所有这些目录在你的系统中都有,这取决于你的内核配置和装载的模块。另外,在/proc下还有三个很重要的目录:net,scsi和sys。Sys目录是可写的,可以通过它来访问或修改内核的参数(见下一部分),而net和scsi则依赖于内核配置。例如,如果系统不支持scsi,则scsi目录不存在。

除了以上介绍的这些,还有的是一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程都有对应的一个目录在 /proc下,以进程的PID号为目录名,它们是读取进程信息的接口。而self目录则是读取进程本身的信息接口,是一个link。Proc文件系统的名字就是由之而起。进程目录的结构如下:

目录名称 目录内容
Cmdline 命令行参数
Environ 环境变量值
Fd 一个包含所有文件描述符的目录
Mem 进程的内存被利用情况
Stat 进程状态
Status 进程当前状态,以可读的方式显示出来
Cwd 当前工作目录的链接
Exe 指向该进程的执行命令文件
Maps 内存映象
Statm 进程内存状态信息
Root 链接此进程的root目录

用户如果要查看系统信息,可以用cat命令。例如:

# cat /proc/interrupts
CPU0
0: 8728810 XT-PIC timer
1: 895 XT-PIC keyboard
2: 0 XT-PIC cascade
3: 531695 XT-PIC aha152x
4: 2014133 XT-PIC serial
5: 44401 XT-PIC pcnet_cs
8: 2 XT-PIC rtc
11: 8 XT-PIC i82365
12: 182918 XT-PIC Mouse
13: 1 XT-PIC fpu PS/2
14: 1232265 XT-PIC ide0
15: 7 XT-PIC ide1
NMI: 0

用户还可以实现修改内核参数。在/proc文件系统中有一个有趣的目录:/proc/sys。它不仅提供了内核信息,而且可以通过它修改内核参数,来优化你的系统。但是你必须很小心,因为可能会造成系统崩溃。最好是先找一台无关紧要的机子,调试成功后再应用到你的系统上。

要改变内核的参数,只要用vi编辑或echo参数重定向到文件中即可。下面有一个例子:

# cat /proc/sys/fs/file-max
4096
# echo 8192 > /proc/sys/fs/file-max
# cat /proc/sys/fs/file-max
8192

如果你优化了参数,则可以把它们写成添加到文件rc.local中,使它在系统启动时自动完成修改。

/proc/scsi
/proc/scsi/scsi
作为系统管理员,需要了解的最有用内容是,在有热交换驱动器情况下,如何不重启系统就可以添加更多磁盘空间。假使不使用 /proc,您可以插入驱动器,但为了使系统识别新磁盘,必须随即重新引导系统。这里,可以用以下命令来使系统识别新的驱动器:

echo "scsi add-single-device w x y z" > /proc/scsi/scsi

为使该命令正常运行,必须指定正确的参数值 w、x、y 和 z,如下所示:
w 是主机适配器标识,第一个适配器为零(0)
x 是主机适配器上的 SCSI 通道,第一个通道为零(0)
y 是设备的 SCSI 标识
z 是 LUN 号,第一个 LUN 为零(0)

一旦将磁盘添加到系统中之后,可以挂装任何先前已格式化的文件系统,也可以开始对它进行格式化等。例如,如果不确定磁盘是什么设备,或者想检查任何先前已有的分区,则可以用如 fdisk -l 这样的命令来向您报告这方面的信息。

相反的,在不重新引导系统的情况下将设备从系统中除去的命令是:

echo "scsi remove-single-device w x y z" > /proc/scsi/scsi

在输入这条命令并将热交换 SCSI 磁盘从系统中除去之前,请确保首先卸下已从该磁盘安装的任何文件系统。

/proc/sys/fs/
/proc/sys/fs/file-max
该文件指定了可以分配的文件句柄的最大数目。如果用户得到的错误消息声明由于打开文件数已经达到了最大值,从而他们不能打开更多文件,则可能需要增加该值。可将这个值设置成有任意多个文件,并且能通过将一个新数字值写入该文件来更改该值。

缺省设置:4096

/proc/sys/fs/file-nr
该文件与 file-max 相关,它有三个值:
已分配文件句柄的数目
已使用文件句柄的数目
文件句柄的最大数目
该文件是只读的,仅用于显示信息。

/proc/sys/fs/inode-*
任何以名称“inode”开头的文件所执行的操作与上面那些以名称“file”开头的文件所执行的操作一样,但所执行的操作与索引节点有关,而与文件句柄无关。

/proc/sys/fs/overflowuid 和 /proc/sys/fs/overflowgid
这两个文件分别保存那些支持 16 位用户标识和组标识的任何文件系统的用户标识(UID)和组标识(GID)。可以更改这些值,但如果您确实觉得需要这样做,那么您可能会发现更改组和密码文件项更容易些。

缺省设置:65534

/proc/sys/fs/super-max
该文件指定超级块处理程序的最大数目。挂装的任何文件系统需要使用超级块,所以如果挂装了大量文件系统,则可能会用尽超级块处理程序。

缺省设置:256

/proc/sys/fs/super-nr
该文件显示当前已分配超级块的数目。该文件是只读的,仅用于显示信息。

/proc/sys/kernel
/proc/sys/kernel/acct
该文件有三个可配置值,根据包含日志的文件系统上可用空间的数量(以百分比表示),这些值控制何时开始进行进程记帐:
如果可用空间低于这个百分比值,则停止进程记帐
如果可用空间高于这个百分比值,则开始进程记帐
检查上面两个值的频率(以秒为单位)
要更改这个文件的某个值,应该回送用空格分隔开的一串数字。

缺省设置:2 4 30

如果包含日志的文件系统上只有少于 2% 的可用空间,则这些值会使记帐停止,如果有 4% 或更多可用空间,则再次启动记帐。每 30 秒做一次检查。

/proc/sys/kernel/ctrl-alt-del
该文件有一个二进制值,该值控制系统在接收到 ctrl+alt+delete 按键组合时如何反应。这两个值表示:
零(0)值表示捕获 ctrl+alt+delete,并将其送至 init 程序。这将允许系统可以完美地关闭和重启,就好象您输入 shutdown 命令一样。
壹(1)值表示不捕获 ctrl+alt+delete,将执行非干净的关闭,就好象直接关闭电源一样。

缺省设置:0

/proc/sys/kernel/domainname
该文件允许您配置网络域名。它没有缺省值,也许已经设置了域名,也许没有设置。

/proc/sys/kernel/hostname
该文件允许您配置网络主机名。它没有缺省值,也许已经设置了主机名,也许没有设置。

/proc/sys/kernel/msgmax
该文件指定了从一个进程发送到另一个进程的消息的最大长度。进程间的消息传递是在内核的内存中进行,不会交换到磁盘上,所以如果增加该值,则将增加操作系统所使用的内存数量。

缺省设置:8192

/proc/sys/kernel/msgmnb
该文件指定在一个消息队列中最大的字节数。

缺省设置:16384

/proc/sys/kernel/msgmni
该文件指定消息队列标识的最大数目。

缺省设置:16

/proc/sys/kernel/panic
该文件表示如果发生“内核严重错误(kernel panic)”,则内核在重新引导之前等待的时间(以秒为单位)。零(0)秒设置在发生内核严重错误时将禁止重新引导。

缺省设置:0

/proc/sys/kernel/printk
该文件有四个数字值,它们根据日志记录消息的重要性,定义将其发送到何处。关于不同日志级别的更多信息,请阅读 syslog(2) 联机帮助页。该文件的四个值为:
控制台日志级别:优先级高于该值的消息将被打印至控制台
缺省的消息日志级别:将用该优先级来打印没有优先级的消息
最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)
缺省的控制台日志级别:控制台日志级别的缺省值

缺省设置:6 4 1 7

/proc/sys/kernel/shmall
该文件是在任何给定时刻系统上可以使用的共享内存的总量(以字节为单位)。

缺省设置:2097152

/proc/sys/kernel/shmax
该文件指定内核所允许的最大共享内存段的大小(以字节为单位)。

缺省设置:33554432

/proc/sys/kernel/shmmni
该文件表示用于整个系统共享内存段的最大数目。

缺省设置:4096

/proc/sys/kernel/sysrq
如果该文件指定的值为非零,则激活 System Request Key。

缺省设置:0

/proc/sys/kernel/threads-max
该文件指定内核所能使用的线程的最大数目。

缺省设置:2048

/proc/sys/net
/proc/sys/net/core/message_burst
写新的警告消息所需的时间(以 1/10 秒为单位);在这个时间内所接收到的其它警告消息会被丢弃。这用于防止某些企图用消息“淹没”您系统的人所使用的拒绝服务(Denial of Service)攻击。

缺省设置:50(5 秒)

/proc/sys/net/core/message_cost
该文件存有与每个警告消息相关的成本值。该值越大,越有可能忽略警告消息。

缺省设置:5

/proc/sys/net/core/netdev_max_backlog
该文件指定了,在接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

缺省设置:300

/proc/sys/net/core/optmem_max
该文件指定了每个套接字所允许的最大缓冲区的大小。

/proc/sys/net/core/rmem_default
该文件指定了接收套接字缓冲区大小的缺省值(以字节为单位)。

/proc/sys/net/core/rmem_max
该文件指定了接收套接字缓冲区大小的最大值(以字节为单位)。

/proc/sys/net/core/wmem_default
该文件指定了发送套接字缓冲区大小的缺省值(以字节为单位)。

/proc/sys/net/core/wmem_max
该文件指定了发送套接字缓冲区大小的最大值(以字节为单位)。

/proc/sys/net/ipv4
所有 IPv4 和 IPv6 的参数都被记录在内核源代码文档中。请参阅文件 /usr/src/linux/Documentation/networking/ip-sysctl.txt。

/proc/sys/net/ipv6
同 IPv4。

/proc/sys/vm
/proc/sys/vm/buffermem
该文件控制用于缓冲区内存的整个系统内存的数量(以百分比表示)。它有三个值,通过把用空格相隔的一串数字写入该文件来设置这三个值。
用于缓冲区的内存的最低百分比
如果发生所剩系统内存不多,而且系统内存正在减少这种情况,系统将试图维护缓冲区内存的数量。
用于缓冲区的内存的最高百分比

缺省设置:2 10 60

/proc/sys/vm/freepages
该文件控制系统如何应对各种级别的可用内存。它有三个值,通过把用空格相隔的一串数字写入该文件来设置这三个值。
如果系统中可用页面的数目达到了最低限制,则只允许内核分配一些内存。
如果系统中可用页面的数目低于这一限制,则内核将以较积极的方式启动交换,以释放内存,从而维持系统性能。
内核将试图保持这个数量的系统内存可用。低于这个值将启动内核交换。

缺省设置:512 768 1024

/proc/sys/vm/kswapd
该文件控制允许内核如何交换内存。它有三个值,通过把用空格相隔的一串数字写入该文件来设置这三个值:
内核试图一次释放的最大页面数目。如果想增加内存交换过程中的带宽,则需要增加该值。
内核在每次交换中试图释放页面的最少次数。
内核在一次交换中所写页面的数目。这对系统性能影响最大。这个值越大,交换的数据越多,花在磁盘寻道上的时间越少。然而,这个值太大会因“淹没”请求队列而反过来影响系统性能。

缺省设置:512 32 8

/proc/sys/vm/pagecache
该文件与 /proc/sys/vm/buffermem 的工作内容一样,但它是针对文件的内存映射和一般高速缓存。

使内核设置具有持久性
这里提供了一个方便的实用程序,用于更改 /proc/sys 目录下的任何内核参数。它使您可以更改运行中的内核(类似于上面用到的 echo 和重定向方法),但它还有一个在系统引导时执行的配置文件。这使您可以更改运行中的内核,并将这些更改添加到配置文件,以便于在系统重新引导之后,这些更改仍然生效。

该实用程序称为 sysctl,在 sysctl(8) 的联机帮助页中,对这个实用程序进行了完整的文档说明。sysctl 的配置文件是 /etc/sysctl.conf,可以编辑该文件,并在 sysctl.conf(8) 下记录了该文件。sysctl 将 /proc/sys 下的文件视为可以更改的单个变量。所以,以 /proc/sys 下的文件 /proc/sys/fs/file-max 为例,它表示系统中所允许的文件句柄的最大数目,这个文件被表示成 fs.file-max。

这个示例揭示了 sysctl 表示法中的一些奇妙事情。由于 sysctl 只能更改 /proc/sys 目录下的变量,并且人们始终认为变量是在这个目录下,因此省略了变量名的那一部分(/proc/sys)。另一个要说明的更改是,将目录分隔符(正斜杠 /)换成了英文中的句号(点 .)。

将 /proc/sys 中的文件转换成 sysctl 中的变量有两个简单的规则:
去掉前面部分 /proc/sys。
将文件名中的正斜杠变为点。

这两条规则使您能将 /proc/sys 中的任一文件名转换成 sysctl 中的任一变量名。一般文件到变量的转换为:

/proc/sys/dir/file --> dir.file
dir1.dir2.file --> /proc/sys/dir1/dir2/file

可以使用命令 sysctl -a 查看所有可以更改的变量和其当前设置。

用 sysctl 还可以更改变量,它所做的工作与上面所用的 echo 方法完全一样。其表示法为:

sysctl -w dir.file="value"

还是用 file-max 作为示例,使用下面两种方法中的一种将该值更改为 16384:

sysctl -w fs.file-max="16384"

或者:

echo "16384" > /proc/sys/fs/file-max


/proc文件系统中网络参数

在/proc/sys/net/ipv4/目录下,包含的是和tcp/ip协议相关的各种参数,下面我们就对这些网络参数加以详细的说明。

ip_forward 参数类型:BOOLEAN
0 - 关闭(默认值)
not 0 - 打开ip转发

在网络本地接口之间转发数据报。该参数非常特殊,对该参数的修改将导致其它所有相关配置参数恢复其默认值(对于主机参阅RFC1122,对于路由器参见RFC1812)

ip_default_ttl 参数类型:INTEGER
默认值为 64 。表示IP数据报的Time To Live值。

ip_no_pmtu_disc 参数类型:BOOLEAN
关闭路径MTU探测,默认值为FALSE

ipfrag_high_thresh 参数类型:整型
用来组装分段的IP包的最大内存量。当ipfrag_high_thresh数量的内存被分配来用来组装IP包,则IP分片处理器将丢弃数据报直到ipfrag_low_thresh数量的内存被用来组装IP包。

ipfrag_low_thresh 参数类型:整型
参见ipfrag_high_thresh。

ipfrag_time 参数类型:整型
保存一个IP分片在内存中的时间。

inet_peer_threshold 参数类型:整型
INET对端存储器某个合适值,当超过该阀值条目将被丢弃。该阀值同样决定生存时间以及废物收集通过的时间间隔。条目越多﹐存活期越低﹐GC 间隔越短

inet_peer_minttl 参数类型:整型
条目的最低存活期。在重组端必须要有足够的碎片(fragment)存活期。这个最低存活期必须保证缓冲池容积是否少于 inet_peer_threshold。该值以 jiffies为单位测量。

inet_peer_maxttl 参数类型:整型
条目的最大存活期。在此期限到达之后﹐如果缓冲池没有耗尽压力的话(例如﹐缓冲池中的条目数目非常少)﹐不使用的条目将会超时。该值以 jiffies为单位测量。

inet_peer_gc_mintime 参数类型:整型
废物收集(GC)通过的最短间隔。这个间隔会影响到缓冲池中内存的高压力。 该值以 jiffies为单位测量。

inet_peer_gc_maxtime 参数类型:整型
废物收集(GC)通过的最大间隔,这个间隔会影响到缓冲池中内存的低压力。 该值以 jiffies为单位测量。

tcp_syn_retries 参数类型:整型
对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右。

tcp_synack_retries 参数类型:整型
对于远端的连接请求SYN,内核会发送SYN + ACK数据报,以确认收到上一个 SYN连接请求包。这是所谓的三次握手( threeway handshake)机制的第二个步骤。这里决定内核在放弃连接之前所送出的 SYN+ACK 数目。

tcp_keepalive_time 参数类型:整型
当keepalive打开的情况下,TCP发送keepalive消息的频率,默认值是2个小时。

tcp_keepalive_probes 参数类型:整型
TCP发送keepalive探测以确定该连接已经断开的次数,默认值是9。

tcp_keepalive_interval 参数类型:整型
探测消息发送的频率,乘以tcp_keepalive_probes就得到对于从开始探测以来没有响应的连接杀除的时间。默认值为75秒,也就是没有活动的连接将在大约11分钟以后将被丢弃。

tcp_retries1 参数类型:整型
当出现可疑情况而必须向网络层报告这个可疑状况之前﹐需要进行多少次重试。最低的 RFC 数值是 3 ﹐这也是默认值﹐根据RTO的值大约在3秒 - 8分钟之间。

tcp_retries2 参数类型:整型
在丢弃激活的TCP连接之前﹐需要进行多少次重试。RFC1122规定,该值必须大于100秒。默认值为15,根据RTO的值来决定,相当于13-30分钟,

tcp_orphan_retries 参数类型:整型
在近端丢弃TCP连接之前﹐要进行多少次重试。默认值是 7 个﹐相当于 50秒 - 16分钟﹐视 RTO 而定。如果您的系统是负载很大的web服务器﹐那么也许需要降低该值﹐这类 sockets 可能会耗费大量的资源。另外参的考 tcp_max_orphans 。

tcp_fin_timeout 参数类型:整型
对于本端断开的socket连接, TCP保持在FIN-WAIT-2状态的时间。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。默认值为 60 秒。过去在2.2版本的内核中是 180 秒。您可以设置该值﹐但需要注意﹐如果您的机器为负载很重的web服务器﹐您可能要冒内存被大量无效数据报填满的风险﹐FIN-WAIT-2 sockets 的危险性低于 FIN-WAIT-1 ﹐因为它们最多只吃 1.5K 的内存﹐但是它们存在时间更长。另外参考 tcp_max_orphans。

tcp_max_tw_buckets 参数类型:整型
系统在同时所处理的最大 timewait sockets 数目。如果超过此数的话﹐time-wait socket 会被立即砍除并且显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐千万不要人为的降低这个限制﹐不过﹐如果网络条件需要比默认值更多﹐则可以提高它(或许还要增加内存)。

tcp_tw_recycle 参数类型:布尔
打开快速 TIME-WAIT sockets 回收。默认值是1。除非得到技术专家的建议或要求﹐请不要随意修改这个值。

tcp_max_orphans 参数类型:整型
系统所能处理不属于任何进程的TCP sockets最大数量。假如超过这个数量﹐那么不属于任何进程的连接会被立即reset,并同时显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐千万不要依赖这个或是人为的降低这个限制

tcp_abort_on_overflow 参数类型:布尔
当守护进程太忙而不能接受新的连接,就象对方发送reset消息,默认值是false。这意味着当溢出的原因是因为一个偶然的猝发,那么连接将恢复状态。只有在你确信守护进程真的不能完成连接请求时才打开该选项,该选项会影响客户的使用。

tcp_syncookies 参数类型:整型
只有在内核编译时选择了CONFIG_SYNCOOKIES时才会发生作用。当出现syn等候队列出现溢出时象对方发送syncookies。目的是为了防止syn flood攻击。默认值是false。

注意:该选项千万不能用于那些没有收到攻击的高负载服务器,如果在日志中出现synflood消息,但是调查发现没有收到synflood攻击,而是合法用户的连接负载过高的原因,你应该调整其它参数来提高服务器性能。参考: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.

syncookie严重的违背TCP协议,不允许使用TCP扩展,可能对某些服务导致严重的性能影响(如SMTP转发)。

tcp_stdurg 参数类型:整型
使用 TCP urg pointer 字段中的主机请求解释功能。大部份的主机都使用老旧的 BSD解释,因此如果您在 Linux 打开它﹐或会导致不能和它们正确沟通。默认值为为﹕FALSE

tcp_max_syn_backlog 参数类型:整型
对于那些依然还未获得客户端确认的连接请求﹐需要保存在队列中最大数目。对于超过 128Mb 内存的系统﹐默认值是 1024 ﹐低于 128Mb 的则为 128。如果服务器经常出现过载﹐可以尝试增加这个数字。警告﹗假如您将此值设为大于 1024﹐最好修改 include/net/tcp.h 里面的 TCP_SYNQ_HSIZE ﹐以保持 TCP_SYNQ_HSIZE*16 0)或者bytes-bytes/2^(-tcp_adv_win_scale)(如果tcp_adv_win_scale 128Mb 32768-61000
0)则系统将忽略所有发送给自己的ICMP ECHO请求或那些广播地址的请求。

icmp_destunreach_rate - 整数
icmp_paramprob_rate - 整数
icmp_timeexceed_rate - 整数
icmp_echoreply_rate - 整数(not enabled per default)
限制发向特定目标的ICMP数据报的最大速率。0表示没有任何限制,否则表示jiffies数据单位中允许发送的个数。

icmp_ignore_bogus_error_responses - 布尔类型
某些路由器违背RFC1122标准,其对广播帧发送伪造的响应来应答。这种违背行为通常会被以告警的方式记录在系统日志中。如果该选项设置为True,内核不会记录这种警告信息。默认值为False。

(1) Jiffie: 内核使用的内部时间单位,在i386系统上大小为1/100s,在Alpha中为1/1024S。在/usr/include/asm/param.h中的HZ定义有特定系统的值。

conf/interface/*:
conf/all/*是特定的,用来修改所有接口的设置,is special and changes the settings for all interfaces.
Change special settings per interface.

log_martians - 布尔类型
记录带有不允许的地址的数据报到内核日志中。

accept_redirects - 布尔类型
收发接收ICMP重定向消息。对于主机来说默认为True,对于用作路由器时默认值为False。

forwarding - 布尔类型
在该接口打开转发功能

mc_forwarding - 布尔类型
是否进行多播路由。只有内核编译有CONFIG_MROUTE并且有路由服务程序在运行该参数才有效。

proxy_arp - 布尔类型
打开proxy arp功能。

shared_media - 布尔类型
发送(路由器)或接收(主机) RFC1620 共享媒体重定向。覆盖ip_secure_redirects的值。默认为True。

secure_redirects - 布尔类型
仅仅接收发给默认网关列表中网关的ICMP重定向消息,默认值是TRUE。

send_redirects - 布尔类型
如果是router,发送重定向消息,默认值是TRUE

bootp_relay - 布尔类型
接收源地址为0.b.c.d,目的地址不是本机的数据报。用来支持BOOTP转发服务进程,该进程将捕获并转发该包。默认为False,目前还没有实现。

accept_source_route - 布尔类型
接收带有SRR选项的数据报。对于主机来说默认为False,对于用作路由器时默认值为True。

rp_filter 参数类型
1 - 通过反向路径回溯进行源地址验证(在RFC1812中定义)。对于单穴主机和stub网络路由器推荐使用该选项。
0 - 不通过反向路径回溯进行源地址验证。
默认值为0。某些发布在启动时自动将其打开。’

/proc --- 一个虚拟文件系统
/proc 文件系统是一种内核和内核模块用来向进程 (process) 发送信息的机制 (所以叫做 /proc)。这个伪文件系统让你可以和内核内部数据结构进行交互,获取 有关进程的有用信息,在运行中 (on the fly) 改变设置 (通过改变内核参数)。 与其他文件系统不同,/proc 存在于内存之中而不是硬盘上。如果你察看文件 /proc/mounts (和 mount 命令一样列出所有已经加载的文件系统),你会看到其中 一行是这样的:



grep proc /proc/mounts
/proc /proc proc rw 0 0

/proc 由内核控制,没有承载 /proc 的设备。因为 /proc 主要存放由内核控制的状态信息,所以大部分这些信息的逻辑位置位于内核控制的内存。对 /proc 进行一次 'ls -l' 可以看到大部分文件都是 0 字节大的;不过察看这些文件的时候,确实可以看到一些信息。这怎么可能?这是因为 /proc 文件系统和其他常规的文件系统一样把自己注册到虚拟文件系统层 (VFS) 了。然而,直到当 VFS 调用它,请求文件、目录的 i-node 的时候,/proc 文件系统才根据内核中的信息建立相应的文件和目录。


加载 proc 文件系统
如果系统中还没有加载 proc 文件系统,可以通过如下命令加载 proc 文件系统:


mount -t proc proc /proc

上述命令将成功加载你的 proc 文件系统。更多细节请阅读 mount 命令的 man page。


察看 /proc 的文件
/proc 的文件可以用于访问有关内核的状态、计算机的属性、正在运行的进程的状态等信息。大部分 /proc 中的文件和目录提供系统物理环境最新的信息。尽管 /proc 中的文件是虚拟的,但它们仍可以使用任何文件编辑器或像'more', 'less'或 'cat'这样的程序来查看。当编辑程序试图打开一个虚拟文件时,这个文件就通过内核中的信息被凭空地 (on the fly) 创建了。这是一些我从我的系统中得到的一些有趣结果:

$ ls -l /proc/cpuinfo
-r--r--r-- 1 root root 0 Dec 25 11:01 /proc/cpuinfo

$ file /proc/cpuinfo
/proc/cpuinfo: empty

$ cat /proc/cpuinfo

processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 8
model name : Pentium III (Coppermine)
stepping : 6
cpu MHz : 1000.119
cache size : 256 KB
fdiv_bug : no
hlt_bug : no
sep_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 2
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
cmov pat pse36 mmx fxsr xmm
bogomips : 1998.85

processor : 3
vendor_id : GenuineIntel
cpu family : 6
model : 8
model name : Pentium III (Coppermine)
stepping : 6
cpu MHz : 1000.119
cache size : 256 KB
fdiv_bug : no
hlt_bug : no
sep_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 2
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
cmov pat pse36 mmx fxsr xmm
bogomips : 1992.29


这是一个从双 CPU 的系统中得到的结果,上述大部分的信息十分清楚地给出了这个系统的有用的硬件信息。有些 /proc 的文件是经过编码的,不同的工具可以被用来解释这些编码过的信息并输出成可读的形式。这样的工具包括:'top', 'ps', 'apm' 等。



得到有用的系统/内核信息

proc 文件系统可以被用于收集有用的关于系统和运行中的内核的信息。下面是一些重要的文件:

/proc/cpuinfo - CPU 的信息 (型号, 家族, 缓存大小等)
/proc/meminfo - 物理内存、交换空间等的信息
/proc/mounts - 已加载的文件系统的列表
/proc/devices - 可用设备的列表
/proc/filesystems - 被支持的文件系统
/proc/modules - 已加载的模块
/proc/version - 内核版本
/proc/cmdline - 系统启动时输入的内核命令行参数
proc 中的文件远不止上面列出的这么多。想要进一步了解的读者可以对 /proc 的每一个文件都'more'一下或读参考文献[1]获取更多的有关 /proc 目录中的文件的信息。我建议使用'more'而不是'cat',除非你知道这个文件很小,因为有些文件 (比如 kcore) 可能会非常长。


有关运行中的进程的信息
/proc 文件系统可以用于获取运行中的进程的信息。在 /proc 中有一些编号的子目录。每个编号的目录对应一个进程 id (PID)。这样,每一个运行中的进程 /proc 中都有一个用它的 PID 命名的目录。这些子目录中包含可以提供有关进程的状态和环境的重要细节信息的文件。让我们试着查找一个运行中的进程。

$ ps -aef | grep mozilla
root 32558 32425 8 22:53 pts/1 00:01:23 /usr/bin/mozilla

上述命令显示有一个正在运行的 mozilla 进程的 PID 是 32558。相对应的,/proc 中应该有一个名叫 32558 的目录


$ ls -l /proc/32558
total 0
-r--r--r-- 1 root root 0 Dec 25 22:59 cmdline
-r--r--r-- 1 root root 0 Dec 25 22:59 cpu
lrwxrwxrwx 1 root root 0 Dec 25 22:59 cwd -> /proc/
-r-------- 1 root root 0 Dec 25 22:59 environ
lrwxrwxrwx 1 root root 0 Dec 25 22:59 exe -> /usr/bin/mozilla*
dr-x------ 2 root root 0 Dec 25 22:59 fd/
-r--r--r-- 1 root root 0 Dec 25 22:59 maps
-rw------- 1 root root 0 Dec 25 22:59 mem
-r--r--r-- 1 root root 0 Dec 25 22:59 mounts
lrwxrwxrwx 1 root root 0 Dec 25 22:59 root -> //
-r--r--r-- 1 root root 0 Dec 25 22:59 stat
-r--r--r-- 1 root root 0 Dec 25 22:59 statm
-r--r--r-- 1 root root 0 Dec 25 22:59 status

文件 "cmdline" 包含启动进程时调用的命令行。"envir" 进程的环境变两。 "status" 是进程的状态信息,包括启动进程的用户的用户ID (UID) 和组ID(GID) ,父进程ID (PPID),还有进程当前的状态,比如"Sleelping"和"Running"。每个进程的目录都有几个符号链接,"cwd"是指向进程当前工作目录的符号链接,"exe"指向运行的进程的可执行程序,"root"指向被这个进程看作是根目录的目录 (通常是"/")。目录"fd"包含指向进程使用的文件描述符的链接。 "cpu"仅在运行 SMP 内核时出现,里面是按 CPU 划分的进程时间。

/proc/self 是一个有趣的子目录,它使得程序可以方便地使用 /proc 查找本进程地信息。/proc/self 是一个链接到 /proc 中访问 /proc 的进程所对应的 PID 的目录的符号链接。



通过 /proc 与内核交互

上面讨论的大部分 /proc 的文件是只读的。而实际上 /proc 文件系统通过 /proc 中可读写的文件提供了对内核的交互机制。写这些文件可以改变内核的状态,因而要慎重改动这些文件。/proc/sys 目录存放所有可读写的文件的目录,可以被用于改变内核行为。

/proc/sys/kernel - 这个目录包含反通用内核行为的信息。 /proc/sys/kernel/{domainname, hostname} 存放着机器/网络的域名和主机名。这些文件可以用于修改这些名字。



$ hostname
machinename.domainname.com

$ cat /proc/sys/kernel/domainname
domainname.com

$ cat /proc/sys/kernel/hostname
machinename

$ echo "new-machinename" > /proc/sys/kernel/hostname

$ hostname
new-machinename.domainname.com



这样,通过修改 /proc 文件系统中的文件,我们可以修改主机名。很多其他可配置的文件存在于 /proc/sys/kernel/。这里不可能列出所有这些文件,读者可以自己去这个目录查看以得到更多细节信息。
另一个可配置的目录是 /proc/sys/net。这个目录中的文件可以用于修改机器/网络的网络属性。比如,简单修改一个文件,你可以在网络上瘾藏匿的计算机。


$ echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

这将在网络上瘾藏你的机器,因为它不响应 icmp_echo。主机将不会响应其他主机发出的 ping 查询。



$ ping machinename.domainname.com
no answer from machinename.domainname.com

要改回缺省设置,只要

$ echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all

/proc/sys 下还有许多其它可以用于改变内核属性。读者可以通过参考文献 [1], [2] 获取更多信息。


结论
/proc 文件系统提供了一个基于文件的 Linux 内部接口。它可以用于确定系统的各种不同设备和进程的状态。对他们进行配置。因而,理解和应用有关这个文件系统的知识是理解你的 Linux 系统的关键。

意外的eBay 4面

为什么说“意外”?
原因有俩:
一 我已经拿到了eBay的暑假实习offer;二 没想到这次长达一个小时的电面是目前为止最为刻骨铭心的。(如果喝葛P泉生病那天能坚持微软亚洲研究院的电面的话可能也是今天这样的心情)。
郁闷但是很高兴:因为我的面经已经相当丰富了,哈哈。

本来接到电话已经是下午4点了,我开始犹豫了一下该不该接上海的这个电话。因为我明天就要去ASK.com实习了,eBay就算了吧。老大也是这么和我说的,他说干脆直接拒了那边,就说去微软了。赫赫,我觉得还是应该礼貌点好,人家这次过来的是eBay产品搜索部的头头了,就当再拿一次面经吧。其实无论是去参加google的笔试还是去拿eBay的offer,或者是投微软和百度,无非就是为了面经,为了给10月份的求职加码,说到底我根本不会去这些地方工作也不会离开杭州去生活个几年的。所以就是面经!

好了,那么就面吧。整整一个小时,我经历了非常刺激的电话面试,那边的那个男人的声音非常低沉,感觉是有些岁数了。他主要还是针对我在搜索领域的知识,非常非常的细节。细节到每一个实现是怎么做的,如果“出现XXX情况又该如何解决”。第二部分是英语,要求我把前面涉及到的一些实现细节用英语描述。感觉很吃力,因为一些专业用语毕竟只停留在阅读水平,而不像自我介绍时那么easy的了。然后,继续用英语说到了算法,我希望把他引向我比较了解的哈希表而不是往B+树走。但是哈希表我真的很了解吗?也许很了解,但是也就停留在书本和简单实现的层次上,对于一些意外的情况也许只能通过项目来提升自己的知识面了,比如亿级的数据量,比如哈希表满了,再比如哈希表到底开多少大是合适的,很多很多。后面讲到了快速排序,虽然用英语和他交流,但是还是以为可以easy过去,因为eBay二面的时候已经有人问过了,不就是O(nlogn)然后递归什么的。这次不同,他的出发点就是考察我对算法的理解和复杂度的分析的理解上,不单纯是一个排序算法了。其间我试图用递归树的来解释时间复杂度,算法导论上的几种方法之一,但是他似乎要我解释为什么可以用递归树来解决算法复杂度的计算。莫非是要我给出证明?太夸张了吧,这不由的让我想到了前些日子的google的一道笔试题目。一身汗。最后又对快速排序的最好最佳情况分别进行了讨论,特别让人感觉恶心的是pivot的选择上面,在这个问题上我们足足讨论了有10分钟,因为它决定了快速排序的worst case。

这个电面飞快地过去,其间老大还洗了个澡,我感觉他怎么洗的那么快。对方给我了一个邮件地址,让我发一份电子版的email给他。就这么结束了。后来还和老大交流了很多细节东西,收获颇多啊,看来没有白费我的一个小时,赫赫。

2007年5月14日星期一

葛P泉害人不浅!

长这么大还第一次上吐下泻!
都是学校后勤部门黑心啊!利益集团重重保护,害的我们学生喝大肠杆菌超标40倍的脏水!这是人干的事情么?!!!

2007年5月9日星期三

Linux系统调用列表

以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数。这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的。

按照惯例,这个列表以man pages第2节,即系统调用节为蓝本。按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统调用,对个别本人稍觉不妥的地方作了一些小的修改,并对所有列出的系统调用附上简要注释。

其中有一些函数的作用完全相同,只是参数不同。(可能很多熟悉C++朋友马上就能联想起函数重载,但是别忘了Linux核心是用C语言写的,所以只能取成不同的函数名)。还有一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数会在前面标上“*”号以示区别。

一、进程控制:

fork 创建一个新进程

clone 按指定条件创建子进程

execve 运行可执行文件

exit 中止进程

_exit 立即中止当前进程

getdtablesize 进程所能打开的最大文件数

getpgid 获取指定进程组标识号

setpgid 设置指定进程组标志号

getpgrp 获取当前进程组标识号

setpgrp 设置当前进程组标志号

getpid 获取进程标识号

getppid 获取父进程标识号

getpriority 获取调度优先级

setpriority 设置调度优先级

modify_ldt 读写进程的本地描述表

nanosleep 使进程睡眠指定的时间

nice 改变分时进程的优先级

pause 挂起进程,等待信号

personality 设置进程运行域

prctl 对进程进行特定操作

ptrace 进程跟踪

sched_get_priority_max 取得静态优先级的上限

sched_get_priority_min 取得静态优先级的下限

sched_getparam 取得进程的调度参数

sched_getscheduler 取得指定进程的调度策略

sched_rr_get_interval 取得按RR算法调度的实时进程的时间片长度

sched_setparam 设置进程的调度参数

sched_setscheduler 设置指定进程的调度策略和参数

sched_yield 进程主动让出处理器,并将自己等候调度队列队尾

vfork 创建一个子进程,以供执行新程序,常与execve等同时使用

wait 等待子进程终止

wait3 参见wait

waitpid 等待指定子进程终止

wait4 参见waitpid

capget 获取进程权限

capset 设置进程权限

getsid 获取会晤标识号

setsid 设置会晤标识号

二、文件系统控制

1、文件读写操作

fcntl 文件控制

open 打开文件

creat 创建新文件

close 关闭文件描述字

read 读文件

write 写文件

readv 从文件读入数据到缓冲数组中

writev 将缓冲数组里的数据写入文件

pread 对文件随机读

pwrite 对文件随机写

lseek 移动文件指针

_llseek 在64位地址空间里移动文件指针

dup 复制已打开的文件描述字

dup2 按指定条件复制文件描述字

flock 文件加/解锁

poll I/O 多路转换

truncate 截断文件

ftruncate 参见truncate

umask 设置文件权限掩码

fsync 把文件在内存中的部分写回磁盘

2、文件系统操作

access 确定文件的可存取性

chdir 改变当前工作目录

fchdir 参见chdir

chmod 改变文件方式

fchmod 参见chmod

chown 改变文件的属主或用户组

fchown 参见chown

lchown 参见chown

chroot 改变根目录

stat 取文件状态信息

lstat 参见stat

fstat 参见stat

statfs 取文件系统信息

fstatfs 参见statfs

readdir 读取目录项

getdents 读取目录项

mkdir 创建目录

mknod 创建索引节点

rmdir 删除目录

rename 文件改名

link 创建链接

symlink 创建符号链接

unlink 删除链接

readlink 读符号链接的值

mount 安装文件系统

umount 卸下文件系统

ustat 取文件系统信息

utime 改变文件的访问修改时间

utimes 参见utime

quotactl 控制磁盘配额

三、系统控制

ioctl I/O总控制函数

_sysctl 读/写系统参数

acct 启用或禁止进程记账

getrlimit 获取系统资源上限

setrlimit 设置系统资源上限

getrusage 获取系统资源使用情况

uselib 选择要使用的二进制函数库

ioperm 设置端口I/O权限

iopl 改变进程I/O权限级别

outb 低级端口操作

reboot 重新启动

swapon 打开交换文件和设备

swapoff 关闭交换文件和设备

bdflush 控制bdflush守护进程

sysfs 取核心支持的文件系统类型

sysinfo 取得系统信息

adjtimex 调整系统时钟

alarm 设置进程的闹钟

getitimer 获取计时器值

setitimer 设置计时器值

gettimeofday 取时间和时区

settimeofday 设置时间和时区

stime 设置系统日期和时间

time 取得系统时间

times 取进程运行时间

uname 获取当前UNIX系统的名称、版本和主机等信息

vhangup 挂起当前终端

nfsservctl 对NFS守护进程进行控制

vm86 进入模拟8086模式

create_module 创建可装载的模块项

delete_module 删除可装载的模块项

init_module 初始化模块

query_module 查询模块信息

*get_kernel_syms 取得核心符号,已被query_module代替

四、内存管理

brk 改变数据段空间的分配

sbrk 参见brk

mlock 内存页面加锁

munlock 内存页面解锁

mlockall 调用进程所有内存页面加锁

munlockall 调用进程所有内存页面解锁

mmap 映射虚拟内存页

munmap 去除内存页映射

mremap 重新映射虚拟内存地址

msync 将映射内存中的数据写回磁盘

mprotect 设置内存映像保护

getpagesize 获取页面大小

sync 将内存缓冲区数据写回硬盘

cacheflush 将指定缓冲区中的内容写回磁盘

五、网络管理

getdomainname 取域名

setdomainname 设置域名

gethostid 获取主机标识号

sethostid 设置主机标识号

gethostname 获取本主机名称

sethostname 设置主机名称

六、socket控制

socketcall socket系统调用

socket 建立socket

bind 绑定socket到端口

connect 连接远程主机

accept 响应socket连接请求

send 通过socket发送信息

sendto 发送UDP信息

sendmsg 参见send

recv 通过socket接收信息

recvfrom 接收UDP信息

recvmsg 参见recv

listen 监听socket端口

select 对多路同步I/O进行轮询

shutdown 关闭socket上的连接

getsockname 取得本地socket名字

getpeername 获取通信对方的socket名字

getsockopt 取端口设置

setsockopt 设置端口参数

sendfile 在文件或端口间传输数据

socketpair 创建一对已联接的无名socket

七、用户管理

getuid 获取用户标识号

setuid 设置用户标志号

getgid 获取组标识号

setgid 设置组标志号

getegid 获取有效组标识号

setegid 设置有效组标识号

geteuid 获取有效用户标识号

seteuid 设置有效用户标识号

setregid 分别设置真实和有效的的组标识号

setreuid 分别设置真实和有效的用户标识号

getresgid 分别获取真实的,有效的和保存过的组标识号

setresgid 分别设置真实的,有效的和保存过的组标识号

getresuid 分别获取真实的,有效的和保存过的用户标识号

setresuid 分别设置真实的,有效的和保存过的用户标识号

setfsgid 设置文件系统检查时使用的组标识号

setfsuid 设置文件系统检查时使用的用户标识号

getgroups 获取后补组标志清单

setgroups 设置后补组标志清单

八、进程间通信

ipc 进程间通信总控制调用

1、信号

sigaction 设置对指定信号的处理方法

sigprocmask 根据参数对信号集中的信号执行阻塞/解除阻塞等操作

sigpending 为指定的被阻塞信号设置队列

sigsuspend 挂起进程等待特定信号

signal 参见signal

kill 向进程或进程组发信号

*sigblock 向被阻塞信号掩码中添加信号,已被sigprocmask代替

*siggetmask 取得现有阻塞信号掩码,已被sigprocmask代替

*sigsetmask 用给定信号掩码替换现有阻塞信号掩码,已被sigprocmask代替

*sigmask 将给定的信号转化为掩码,已被sigprocmask代替

*sigpause 作用同sigsuspend,已被sigsuspend代替

sigvec 为兼容BSD而设的信号处理函数,作用类似sigaction

ssetmask ANSI C的信号处理函数,作用类似sigaction

2、消息

msgctl 消息控制操作

msgget 获取消息队列

msgsnd 发消息

msgrcv 取消息

3、管道

pipe 创建管道

4、信号量

semctl 信号量控制

semget 获取一组信号量

semop 信号量操作

5、共享内存

shmctl 控制共享内存

shmget 获取共享内存

shmat 连接共享内存

shmdt 拆卸共享内存

[ZZ]我对const的总结(整理)

发信人: olddog (汪汪汪), 信区: C++
标 题: 我对const的总结(整理)
发信站: 飘渺水云间 (Thu Jul 4 21:04:12 2002), 转信

1. Const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。
注意一点:const可以避免不必要的内存分配
#define STRING "abcdefghijklmn\n"
const char string[]="abcdefghijklm\n";
...
printf(STRING); //为STRING分配了第一次内存
printf(string); //为string一次分配了内存,以后不再分配
...
printf(STRING); //为STRING分配了第二次内存
printf(string);
...
由于const定义常量从汇编的角度来看,只是给出了对应的内存地址,
而不是象#define一样给出的是立即数,所以,const定义的常量在
程序运行过程中只有一份拷贝,而#define定义的常量在内存中有
若干个拷贝。

另外:const可以限定符声明变量只能被读 ,可以便于进行类型检查 , 必须初始化;


2.const的重要特点:
C++的编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高,同时,这也是它取代预定义语句的重要基础。这是因为编译器不会去读存储的内容,如果编译器为const分配了存储空间,它就不能够成为一个编译期间的常量了。 另外:const会由编译器对它进行类型的检测。其实,最主要记住一点 const是向左结合的!!!

const出现位置(example)
<1>
const int i = 0;
const char * a;
char * const cp;
<2>
const T1 func(T2)
const char * func(T2)
char * const func(T2)
T1 func(T2) const
T1 func(const char *)
T1 func(char * const T2)


意义
<1>
char * const cp ;//const pointer to char
char const * cp; //pointer to const char
const char * pc; //pointer to const char
从右往左读


3.const的应用
a. const指针和指针const: 注意const是左结合的;
b. const限定了函数的传递值(引用)参数;
c. const限定函数的返回值;



4.与类有关的const;

a.const成员函数;
class MyClass
{
public:
  int Fun() const;
}
const 后置的形式是一种规定,亦为了不引起混淆。在此函数的声明中和定义中均要使用const,因为const已经成为类型信息的一部分。获得能力:可以操作常量对象。失去能力:不能修改类的数据成员,不能在函数中调用其他不是const的函数。
1)类成员函数后加const不能修改类的除了mutable以外的成员变量
2)非const对象 调用 非const函数, 若不存在则调用相应的const版本
3)const对象只能调用const成员函数

const char * func(T2) 这是返回值是const对象的非const函数;


b. const成员变量;
  类型修饰符const不仅可以说明成员函数,也可以说明数据成员。由于const类型对象必须被初始化,并且不能更新,因此,在类中说明了const数据成员时,只能通过成员初始化列表的方式来生成构造函数对数据成员初始化。
例如:
class A
{
public:
A(int i);
const int &r;
private:
const int a;
static const int b;
};

const int A::b=10; //static const init
A::A(int i):a(i), r(a) //const init in constructor
{
}

例如下面有这样一个例子:
class A
{
void func1() const //NO.1
{}
void func1() //NO.2
{}
void func2() const //NO.3
{}
void func3() //NO.4
{}
}

const A ca;
A a;

a.func1();//call NO.2
a.func2();//call NO.3
a.func3();//call NO.4

ca.func1();//call NO.1
ca.func2();//call NO.3
ca.func3();//error

是不是const的常量值一定不可以被修改呢?
观察以下一段代码:
const int i=0;
int *p=(int*)&i;
p=100;
通过强制类型转换,将地址赋给变量,再作修改即可以改变const常量值。

--

2007年5月8日星期二

以高市盈率筑起中国股市的长城

纵观中国15年的证券市场发展史,凡行情“牛”转“熊”或“熊”转“牛”,无非以下三因素:管理层打压或扶持、主力做空或做多、股民看空或看多。其中,最值得重视的是管理层态度。1999年“5.19”行情的发动、2001年从2245点跌至998点就是典型案例。

此次人代会上温总理的工作报告强调,要稳定发展证券市场。中央要的是一个配合国营大、中型企业改制、有利宏观经济调控的股市。

让我们来体会一下最高管理层的良苦用心:

2月份开始的有关中国股市“泡沫”的大争论为什么嘎然而止?“泡沫论”的主导人之一的全国人大副委员长成思危为什么会改口?什么人、什么力量才能使成思危改口?

证监会面对当前股市的强劲上涨,除了对市场违规操作行为进行监管以外,一概不发声音,并且证监会批准发行的许多新股市盈率允许高达50倍以上。这是为什么?

为什么《人民日报》对市盈率泡沫的评价则是总体健康?

为什么以左小蕾为代表的有海外资金背景的所谓经济学家、专家,从1300点就开始唱空中国股市,到现在已经2800点,股市仍不回调,于是便要求最高管理层对股市进行政策干预。但管理层对其似乎并不理会?

QFII(境外合格投资者)要求增加证券投资额度,但管理层为什么至今未松口子?

国家为什么从明年起要统一内、外资企业所得税率为25%(目前内资企业一般为33%,外资企业为15--18%)?

国家为什么决定由国务院牵头成立对外投资公司,将目前过多的外汇储备引导到去国外投资?

近日国家发改委经济研究院的研究报告向中央建议:对当前我国的资本流动性过剩的现象,要采取利用流动性的方针政策,通过资本市场将过剩的资金配置到急需产业升级的重工化基础制造业。国家发改委是在什么背景下?为什么会提出这样的报告?

答案是:管理层希望股市市盈率维持在高位,不希望我国金融开放(以于2006年12月11日正式开放)后,外资有在低位进入股市而在高位套现的机会,从而避免中国出现类似1997年的东南亚金融风波和90年代初期日本证券市场遭遇国际游资抽资的风险。

市盈率60倍高不高?在2001年6月上证指数达2245点时,股市由此开始变盘下行,进入漫漫熊市。当时,其相应的整体市盈率为62倍,一年期存款利率同现在差不多,而企业的平均盈利水平只有2006年的60%左右。而现在,中国经济已是今非昔比,上市公司平均年复合增长30%以上,市盈率60倍明显不算高。平均市盈率60倍所对应的上证指数为4320点左右。

上市企业利润按25%复合增长(2006年末已经超过25%)计算,到2007年末,涨到5400点的市盈率还是60倍,到2008年末涨到6750点还是60倍,到2009年末涨到8450点还是60倍,到2010年末涨到10550点,市盈率还是60倍......

有理由认为,这就是管理层认可60倍市盈率的理由!

管理层之所以对股市加以呵护,应该是出于以下几点考虑:

首先,可以分流过剩的流动性(见著名经济学家、复旦大学谢百三教授的观点);

其次,为企业特别是产业升级的重工化基础行业的龙头企业发展筹措资金;

第三,可以避免承担巨额的银行坏帐损失。

第四,管理层通过股市要实现更多的国有企业改制和企业投资主体多元化。

发改委研究院王小广说的很透彻:

“股市热一点要比房市热一点更好。可以考虑利用流动性过剩的机会,通过股市的发展来促进产业结构升级,通过产业政策与资本市场结合,大力发展代表产业升级方向的重化工业、装备制造业和现代制造业,促进国民经济竞争力的提高。”

我国前几年搞的中、小国企业改制很不理想,很多国有资产被低于净资产值贱卖,甚至几乎是送给了私营企业的老板。而其间,滋生许多腐败。目前,国家手里所剩企业多为规模大、效益好的企业,如果再采取这样的方式改制,势必会给国家造成巨大的经济损失,也不利于社会稳定。而采取在股市上出让,无疑是一个很好的办法,不仅可以卖个更好的价钱,增加国家财政收入,而且可以实现参与证券投资的广大民众利益均沾,相对比较合理。

上述理由,便是管理层认可高市盈率的原因。种种政策迹象表明,中国管理层不希望外资大量流入股市!

股市的高市盈率将逼使国际游资面对中国股市望而却步,只好向低市盈率的其它国家的市场流动!日本经济十年大萧条的一个最主要因素,就是国际资本在东京证券交易所疯狂掠夺日本经济高速增长的成果后一走了之。

中国现在和以前大不一样,高额的外汇储备和庞大的过剩流动资金清楚地表明,引进外资已经没有太多的必要。我们没有必要再让外资来分享我国经济高速增长的蛋糕。甚至,中央已经决定在境外上市的公司,要象交通银行一样逐步回国内上市,不能轻易地让国际货币资本占有我中国人民创造的劳动财富。所以管理层最近出台一系列政策,限制外资入市、打击地下钱庄。

国家已经公开表明,今年要重点推动国有大型企业整体上市。今后一段时期,国有上市公司将有3万多亿的优质资产注入。而每一笔国有资产走向股市,就是一次给全民分享福利的机会。我们民族的财富自然只能属于我们。

这样分析,就不难理解为什么管理层不愿大幅增加QFII的额度了。也不难理解为什么QFII老是唱空中国股市。

要构建和谐社会,真正最直接代表广大中国人民利益的事情,就是要将党的11届3中全会以来,中国改革开放30年的经济成果,通过股市这个平台,让我们中国人民自己来分享,而不是让外国人来分享!全民持股,就是国民共享我国经济高速增长30年来的经济成果!就是有中国特色的社会主义的本质体现!

对此,老外们看不懂,证券洋帮办也看不懂。因为他们只懂“经济学”不知道“政治经济学”为何物!他们习惯于用静态市盈率论事,而不愿意用动态市盈率看问题;在理论方面,他们只知道科技创新是革命,而不知道制度创新是最伟大的革命。

在这场没有硝烟的战争中,美国想干什么?美国在干什么?现在已经非常清楚,他们就是要通过美圆对人民币的贬值和促使人民币在资本项目下的自由兑换,来达到鲸吞中国人民创造的巨额物质财富的目的。

这是一场新形势下两种社会形态及其价值理念的较量!为了中华民族的利益,管理层应该也必将用高市盈率筑起中国证券市场的长城,以奋起抵抗国际资本的入侵!

我们正面临一个百年的历史性大机遇。这个机遇就是要创造一个高市盈率的证券市场。任何犹豫不决和小富即安的思想都会使你感到遗憾!

[ZZ]随机垃圾收集

http://linux.chinaunix.net/bbs/archiver/tid-893113.html
随机垃圾收集

内存管理作为资源管理的一种形式一直以来就是软件开发中的难题,大部分编程错误都出现在和内存操作有关的代码中,几十年来内核程序员一直在寻求更好的内存管理机制。事实证明,有效的资源管理技术是绝大多数软件开发从业人员所难以掌握的。因此,早在20世纪60年代垃圾收集就已经随着LISP的发明而被提出并广泛关注,以试图提供一种自动化的内存管理机制。虽然历经了长期发展,在解释型语言中成功的广泛应用,并且不断以程序库的方式向C/C++这种系统级开发语言中渗透,但是作为一种自动化资源管理机制还远未达到广泛适用,尤其是系统及软件的要求。因此在前人的研究基础上,以节点复制为基本框架,结合系统开发中的内存管理的实际,采用随机收集算法,提出一种适用度广泛的新型垃圾收集算法,并可应用于编译器和操作系统的内存管理、闪存文件系统等方面开发之中。
David在Lcc开发中大量使用的一种基于对象生存周期的内存管理方式Arena。Arena是先分配一个内存块,然后再从该内存块中分配内存数据,在整块内的节点都死亡后一次释放整个内存块,从而大大简化了代码,消除了存储漏洞,并避免了内存泄露和重复释放的问题。而其缺点就是可能需要更多的内存空间,并且可能出现悬挂引用,更重要的是这种生存周期确定并一致特例在现实中很少存在。节点复制是一种高效,接口、模型最为简洁的收集方法,唯一的诟病就是庞大的内存需求。结合节点复制的优点,改进这个内存管理模型,仍然是先分配一个内存块,然后再从该内存块中分配内存数据。然而由于对象生存周期的不确定性,在一段时间后不是释放整个内存块,而是扫描整个块看其中还有没有存活的数据,将存活数据复制到一个新块中去再释放该块。
由于是将内存分块分配和收集,而不是分成两个半区,只是一个块一个块的收集,减小了收集的范围,缩短了因收集而产生的中断。如果程序总共用N个块的话用于垃圾收集的内存为1/N,而不是1/2,所以又降低了节点复制方法的内存占用率。因为节点复制算法是搬迁式的,所以同时还消除了内存碎片,从而又降低了分配对象的代价。
为进一步提高性能,就要考虑收集的顺序。大多数商用系统会采用类似“中断”的方式进行收集,然而和外设不同的是,内存没有计算能力,所有关于内存的计算都是靠CPU来完成的,在这里,“中断”方式仍然是线性的if-else形式。因此,采用“中断”收集方式并不比“轮询”收集方式要好。
简单的自加1或自减1的偏序操作的代价是非常低的,那么是顺序收集还是逆序收集呢?一般不会考虑逆序收集,因为很多操作系统都会尽可能的从低地址连续分配内存,逆序收集无疑会扫描很多空白区域,所以顺序收集是个不错的方法。然而访问内存总不像访问寄存器那样直接,况且不同的机器的内存的容量和数量又是不尽相同的,不同的内存的硬件访问方式也是不同的,再加上与cache的关系,用随机访问来掩盖差异是在合适不过的了。
采用随机的收集顺序,一个random()并不会带来多高的代价但却会有很好的效果。收集正在使用的块是一件很麻烦的事情,会造成很大的性能损失,如果总共有N块内存的话,当前使用率为n/N(通常n不会很大),收集率为1/N,收集到当前使用块的概率为n/N^2,机会还是很小的。而每块被收集到的概率是相等的,又不会出现某些块总被收集到某些块却总也收集不到的现象。
充分利用内存会得到很好的性能,就不一定会固守尽可能从低地址连续分配内存的主观教条,从而整个内存空间的使用状况是离散的,这样就会更加适合于使用随机收集的方式。
闪存和内存存在一定程度上的相似性,而现在闪存文件系统也需要某种有效的垃圾收集机制的支持,因此我将此收集算法改造出一个适用于闪存文件系统的变体。因为现在广泛使用的Nand_Flash需要按块读写,所以该收集算法还可用于基于Nand_Flash的闪存文件系统。Nand_Flash有擦写次数寿命的限制,需要写均衡技术的支持,对此我们只要把新块分配到尚未使用的新块中,即可达到写均衡的效果。由于Nand_Flash会随机的产生坏块,使用该收集算法可以不把物理坏块映射到任何逻辑块上,使得文件系统在逻辑层上是连续可用的。
为进一步提高收集效率还可以采取分代的策略,并把那些生存周期确定不变的数据(如C语言中的全局变量)放在一个块中并且不对该块进行扫描,让该块随着程序的结束而被释放,对于那些大型数据,进行标记远比复制的代价要小得多。
为了避免直接使用ANSI/ISO C的malloc()和free()函数而造成的内存碎片和操作时间不确定等问题,著名实时内核MicroC/OS-II把连续大块内存分区,每个分区又分成一些大小相同的块来进行管理。如果将该收集算法加以改进并应用在操作系统的内存管理和虚拟内存管理模块中,按区、块收集内存,简化了内存管理和虚拟内存管理的模型,同时也解决了内存碎片的问题,给整个系统和应用程序提供更有效的存储管理机制,从而带来更好的性能。在操作系统层面上提供垃圾收集机制不仅性能更好,又使得垃圾收集机制在整个系统上是统一的,而不必分别在不同的编译器和应用程序上实现垃圾收集机制,以避免一个系统中存在多个垃圾收集机制而造成的资源浪费和潜在的冲突。