apache MPM 公共指令
说明 | 收集了被多个多路处理模块(MPM)实现的公共指令 |
---|---|
状态 | MPM |
AcceptMutex 指令
说明 | Apache用于串行化多个子进程在(多个)网络套接字(socket)上接受请求的方法 |
---|---|
语法 | AcceptMutex Default|method |
默认值 | AcceptMutex Default |
作用域 | server config |
状态 | MPM |
模块 |
prefork , worker
|
AcceptMutex
指令用于设置串行化多个子进程在(多个)网络套接字上接受请求的方法。在2.0版本以前,只能在编译时设定此方法。应当在这里使用的最佳方法取决于不同的硬件体系结构和操作系统。欲知详情,请参见性能调节文档。
如果设置为Default
,那么将会使用编译时自动选择的默认值。其他可用的方法在下面列出。注意,并不是所有的方法在所有的平台上都是可用的,如果指定了一个不可用的方法,将会在错误日志中记录下这个不可用的方法。
flock
- 这种方法调用系统函数
flock(2)
来锁定一个加锁文件(其位置取决于LockFile
指令)。 fcntl
- 这种方法调用系统函数
fcntl(2)
来锁定一个加锁文件(其位置取决于LockFile
指令)。 posixsem
- (2.0及更新版本)这种方法使用了POSIX信号灯。如果一个运行中的线程占有了互斥segfault ,则信号灯的所有者将不会被恢复,从而导致服务器的挂起和失去响应。
pthread
- (1.3及更新版本)这种方法使用了POSIX互斥,按理应该可以用于所有完整实现了POSIX线程规范的体系中,但是似乎只能用在Solaris2.5及更新版本中,甚至只能在某种配置下才正常运作。如果遇到这种情况,则应该提防服务器的挂起和失去响应。只提供静态内容的服务器可能不受影响。译者注:此选项不能用于Linux。
sysvsem
- (1.3及更新版本)这种方案使用SysV风格的信号灯以实现互斥。不幸的是,SysV风格的信号灯有一些副作用,其一是,Apache有可能不能在结束以前释放这种信号灯(见
ipcs()
的man page),另外,这种信号灯API给与网络服务器有相同uid的CGI提供了拒绝服务攻击的机会(所有CGI,除非用了类似suexec
或cgiwrapper
)。鉴于此,在多数体系中都不用这种方法,除了IRIX(因为加锁文件的方法在IRIX中代价太高)。
如果你想知道编译时自动选择的默认值,你可以将LogLevel
设为debug
,这样默认的AcceptMutex
就会记录到ErrorLog
中。
警告
在大多数系统上,使用pthread
时,如果一个子进程在持有AcceptCntl
互斥信号时异常中止,服务器将会挂起和失去响应,此时必须手动重启服务器才能解决问题。但Solaris是一个例外,因为它提供了一个机制(Apache利用了该机制),允许在一个持有互斥信号的子进程异常中止后恢复互斥信号。
如果你的操作系统实现了pthread_mutexattr_setrobust_np()
函数,基本上就能安全的使用pthread
选项。译者注:Solaris实现了此函数,Linux却没有实现。
CoreDumpDirectory 指令
说明 | Apache使用的内核转储目录 |
---|---|
语法 | CoreDumpDirectory directory |
默认值 | 参见说明 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_winnt , prefork , worker
|
这个指令用于控制Apache使用的内核转储目录。默认位于ServerRoot
下,因为这个目录通常对于运行服务器的用户是不可写的,内核转储一般也就不会写入内容。如果你在调试中需要内核转储,你可以用这个指令来指定另外一个目录。
Linux上的内核转储
如果Apache以root身份启动并切换至其他用户,即使指定的转储目录对进程是可写的,Linux内核也将禁止Apache进行内核转储。但是Apache2.0.46及以后的版本在你明确指定CoreDumpDirectory
的情况下,能够在Linux2.4以上的版本中强制实现内核转储。
EnableExceptionHook 指令
说明 | 在子进程崩溃以后启用一个钩子来运行异常处理程序 |
---|---|
语法 | EnableExceptionHook On|Off |
默认值 | EnableExceptionHook Off |
作用域 | server config |
状态 | MPM |
模块 |
prefork , worker
|
兼容性 | 仅在 Apache 2.0.49 及以后的版本中可用 |
因为安全原因,这个指令仅在编译时使用了 --enable-exception-hook
选项的情况下才可用。它会在一个子进程崩溃以后启用一个钩子(hook)来运行一个外部模块以做些后继处理。
目前有两个模块(mod_whatkilledus
和mod_backtrace
)可以被钩子使用。请参见Jeff Trawick的EnableExceptionHook site以获得更多信息。
GracefulShutdownTimeout 指令
说明 | 指定优雅停止服务器的超时秒数 |
---|---|
语法 | GracefulShutDownTimeout seconds |
默认值 | GracefulShutDownTimeout 0 |
作用域 | server config |
状态 | MPM |
模块 |
prefork , worker , event
|
兼容性 | 仅在 Apache 2.2 及以后的版本中可用 |
GracefulShutdownTimeout
设置服务器在收到"优雅停止"信号后最多允许使用多少秒来处理尚未完成的连接,超时后服务器将强行退出。
设为"0"表示永不超时,也就是服务器必须在处理完所有尚未完成的请求之后才能退出。
Group 指令
说明 | 对请求提供服务的Apache子进程运行时的用户组 |
---|---|
语法 | Group unix-group |
默认值 | Group #-1 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpmt_os2 , prefork , worker
|
兼容性 | Apache2.0以后只对全局配置有效 |
Group
指令指定了用于对客户端请求提供服务的Apache子进程运行时的用户组。为了使用这个指令,Apache必须以root
初始化启动,否则在切换用户组时会失败,并继续以初始化启动时的用户组运行。Unix-group可以是下列之一:
- 用户组的名称
- 通过名称引用组。
- "
#
"号后跟一个组编号(GID) - 通过编号引用组。
示例
Group www-group
建议你专门为Apache服务器新建一个用户组。一些管理员使用nobody
用户,但是这并非总是可用或是合适的。
安全
不要将Group
(或User
)设置成root
,除非你明确知道自己在做什么,并且明白其风险所在。
特别提示:在<VirtualHost>
段中使用该指令已经不再被支持了。你可以使用suexec
的SuexecUserGroup
指令来达到这个目的。
注意
虽然Group
指令也存在于beos
和mpmt_os2
MPM中,但是事实上没用任何用处,只不过是个摆饰罢了。
Listen 指令
说明 | 服务器监听的IP地址和端口 |
---|---|
语法 | Listen [IP-address:]portnumber [protocol] |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_netware , mpm_winnt , mpmt_os2 , prefork , worker , event
|
兼容性 | Apache2.0以后必须设置该指令,protocol参数仅在2.1.5及以后版本中可用 |
Listen
指令指示Apache只在指定的IP地址和端口上监听;默认情况下Apache会在所有IP地址上监听。Listen
是一个必须设置的指令。如果在配置文件中找不到这个指令,服务器将无法启动。这和先前的版本不一样。
Listen
指令指定服务器在那个端口或地址和端口的组合上监听接入请求。如果只指定一个端口,服务器将在所有地址上监听该端口。如果指定了地址和端口的组合,服务器将在指定地址的指定端口上监听。
使用多个Listen
指令可以指定多个不同的监听端口和/或地址端口组合。服务器将会对列出的所有端口和地址端口组合上的请求作出应答。
例如,想要服务器接受80和8000端口上的请求,可以这样设置:
Listen 80
Listen 8000
为了让服务器在两个确定的地址端口组合上接受请求,可以这样设置:
Listen 192.170.2.1:80
Listen 192.170.2.5:8000
IPv6地址必须像下面的例子一样,用方括号括起来:
Listen [2001:db8::a00:20ff:fea7:ccea]:80
可选的protocol参数在大多数情况下并不需要。若未指定该参数,则将为443端口使用默认的Https
协议,为其它端口使用http
协议。在这里指定协议是为了确定使用哪个模块来处理请求,以及根据AcceptFilter
指令根据不同的协议有针对性的进行优化。
仅在使用非标准端口时才需要指定protocol参数。比如在8443端口运行https
协议:
Listen 192.170.2.1:8443 https
错误条件
多个Listen
指令指定了同一个地址和端口的组合后,会导致"Address already in use
"错误。
参见
- DNS问题
- 地址和端口绑定
ListenBackLog 指令
说明 | 半链接(pending connection)队列的最大长度 |
---|---|
语法 | ListenBacklog backlog |
默认值 | ListenBacklog 511 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_netware , mpm_winnt , mpmt_os2 , prefork , worker
|
半链接(pending connection)队列的最大长度。一般不需要调整此项参数,然而在一些系统上,必须增大此值以抵御TCP SYN 洪水攻击。参见操作系统的listen(2)
系统调用的后备参数。
操作系统常常将此值限制为一个较小的数字,具体根据操作系统的不同而不同。需要注意的是,许多操作系统并不是正好使用后备数值,而是取决于设置的值(通常大于后备值)。
LockFile 指令
说明 | 接受串行锁文件的位置 |
---|---|
语法 | LockFile filename |
默认值 | LockFile logs/accept.lock |
作用域 | server config |
状态 | MPM |
模块 |
prefork , worker
|
LockFile
指令设置当AcceptMutex
指令的值是fcntl
或flock
的时候,Apache使用的锁文件的位置。该指令通常保持它的默认值。改变默认值的主要原因是logs
目录位于一个NFS文件系统上,因为锁文件必须位于本地磁盘上。主服务器进程的PID会自动添加到文件名后面。
安全
最好不要将此文件放在任何人都可以具有写权限的目录(比如/var/tmp
)中,因为别人可以通过建立一个与服务器企图建立的锁文件同名的文件,来阻止服务器启动,从而造成一个拒绝服务攻击。
参见
AcceptMutex
MaxClients 指令
说明 | 允许同时伺服的最大接入请求数量 |
---|---|
语法 | MaxClients number |
默认值 | 参见下面的说明 |
作用域 | server config |
状态 | MPM |
模块 |
beos , prefork , worker
|
MaxClients
指令设置了允许同时伺服的最大接入请求数量。任何超过MaxClients
限制的请求都将进入等候队列,直到达到ListenBacklog
指令限制的最大值为止。一旦一个链接被释放,队列中的请求将得到服务。
对于非线程型的MPM(也就是prefork
),MaxClients
表示可以用于伺服客户端请求的最大子进程数量,默认值是256
。要增大这个值,你必须同时增大ServerLimit
。
对于线程型或者混合型的MPM(也就是beos
或worker
),MaxClients
表示可以用于伺服客户端请求的最大线程数量。线程型的beos
的默认值是50
。对于混合型的MPM默认值是16
(ServerLimit
)乘以25
(ThreadsPerChild
)的结果。因此要将MaxClients
增加到超过16个进程才能提供的时候,你必须同时增加ServerLimit
的值。
MaxMemFree 指令
说明 | 主内存分配程序在未调用free() 的情况下允许持有的最大自由内存数量(KB) |
---|---|
语法 | MaxMemFree KBytes |
默认值 | MaxMemFree 0 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_netware , prefork , worker , mpm_winnt
|
MaxMemFree
指令用于设置主内存分配程序在未调用free()
的情况下允许持有的最大自由内存数量(KB)。若未设置或设置为"0",将表示无限制。
MaxRequestsPerChild 指令
说明 | 每个子进程在其生存期内允许伺服的最大请求数量 |
---|---|
语法 | MaxRequestsPerChild number |
默认值 | MaxRequestsPerChild 10000 |
作用域 | server config |
状态 | MPM |
模块 |
mpm_netware , mpm_winnt , mpmt_os2 , prefork , worker
|
MaxRequestsPerChild
指令设置每个子进程在其生存期内允许伺服的最大请求数量。到达MaxRequestsPerChild
的限制后,子进程将会结束。如果MaxRequestsPerChild
为"0
",子进程将永远不会结束。
不同的默认值
在mpm_netware
和mpm_winnt
上的默认值是"0
"。
将MaxRequestsPerChild
设置成非零值有两个好处:
- 可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
- 给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
注意
对于KeepAlive
链接,只有第一个请求会被计数。事实上,它改变了每个子进程限制最大链接数量的行为。
MaxSpareThreads 指令
说明 | 最大空闲线程数 |
---|---|
语法 | MaxSpareThreads number |
默认值 | 参见下面的说明 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_netware , mpmt_os2 , worker
|
设置最大空闲线程数。不同的MPM对这个指令的处理是不一样的:
worker
的默认值是"250
"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太多,子进程将杀死多余的空闲线程。
mpm_netware
的默认值是"100
"。既然这个MPM只运行单独一个子进程,此MPM当然亦基于整个服务器监视空闲线程数。
beos
和mpmt_os2
的工作方式与mpm_netware
差不多,beos
的默认值是"50
";mpmt_os2
的默认值是"10
"。
限制
MaxSpareThreads
的取值范围是有限制的。Apache将按照如下限制自动修正你设置的值:
-
mpm_netware
要求其小于等于MinSpareThreads
-
worker
要求其大于等于MinSpareThreads
加上ThreadsPerChild
的和
参见
MinSpareThreads
StartServers
MinSpareThreads 指令
说明 | 最小空闲线程数 |
---|---|
语法 | MinSpareThreads number |
默认值 | 参见下面的说明 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_netware , mpmt_os2 , worker
|
设置最小空闲线程数,用于处理可能到来的突发请求。不同的MPM对这个指令的处理是不一样的:
worker
的默认值是"75
"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的空闲线程。
mpm_netware
的默认值是"10
"。既然这个MPM只运行单独一个子进程,此MPM当然亦基于整个服务器监视空闲线程数。
beos
和mpmt_os2
的工作方式与mpm_netware
差不多,beos
的默认值是"1
";mpmt_os2
的默认值是"5
"。
参见
MaxSpareThreads
StartServers
PidFile 指令
说明 | 服务器用于记录父进程(监控进程)PID的文件 |
---|---|
语法 | PidFile filename |
默认值 | PidFile logs/httpd.pid |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_winnt , mpmt_os2 , prefork , worker
|
PidFile
指令设置服务器用于记录父进程(监控进程)PID的文件。如果指定的不是绝对路径,那么将视为基于ServerRoot
的相对路径。
示例
PidFile /var/run/apache.pid
这个文件通常用来便于给服务器父进程发送一个信号,用于关闭或重启服务器,以重新打开ErrorLog
和TransferLog
文件、重新读取配置文件。这些可以通过发送一个"SIGHUP"(kill -1)信号到PidFile
记录的进程PID。
PidFile
和其他日志文件一样要注意放置位置和安全问题。
注意
从Apache2开始,推荐使用apachectl
脚本来启动或停止服务器。
ReceiveBufferSize 指令
说明 | TCP接收缓冲区大小(字节) |
---|---|
语法 | ReceiveBufferSize bytes |
默认值 | ReceiveBufferSize 0 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_netware , mpm_winnt , mpmt_os2 , prefork , worker
|
这个指令设置服务器的TCP接收缓冲区的大小(字节)。提高这个值会导致两个后果:高速度和高潜伏时间(100ms左右)。
如果设置为"0
",将使用操作系统默认值。
ScoreBoardFile 指令
说明 | 存储子进程协调数据(coordination data)的文件 |
---|---|
语法 | ScoreBoardFile file-path |
默认值 | ScoreBoardFile logs/apache_status |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_winnt , prefork , worker
|
Apache使用记分板(scoreboard)在父进程和子进程之间进行通信。一些体系结构要求有一个文件来帮助通信。如果未指定这个文件,Apache会首先尝试在匿名共享内存中建立完整的记分板(scoreboard),若失败,将继续尝试使用基于文件的共享存储器在磁盘上建立这个文件。若利用这个指令指定这个文件的位置,则Apache将总是在磁盘上建立这个文件。
示例
ScoreBoardFile /var/run/apache_status
基于文件的共享存储器对于使用直接访问记分板(scoreboard)的第三方程序是很有用的。
将ScoreBoardFile
放置在RAM disk中会对速度提升有很大帮助。但是同其他日志文件一样也要注意放置位置和安全问题。
参见
- 停止和重启Apache
SendBufferSize 指令
说明 | TCP发送缓冲区大小(字节) |
---|---|
语法 | SendBufferSize bytes |
默认值 | SendBufferSize 0 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_netware , mpm_winnt , mpmt_os2 , prefork , worker
|
这个指令设置服务器的TCP发送缓冲区的大小(字节)。提高这个值会导致两个后果:高速度和高潜伏时间(100ms左右)。
如果设置为"0
",将使用操作系统默认值。
ServerLimit 指令
说明 | 服务器允许配置的进程数上限 |
---|---|
语法 | ServerLimit number |
默认值 | 参见下面的说明 |
作用域 | server config |
状态 | MPM |
模块 |
prefork , worker
|
对于prefork
MPM,这个指令设置了MaxClients
最大允许配置的数值。对于worker
MPM,这个指令和ThreadLimit
结合使用设置了MaxClients
最大允许配置的数值。任何在重启期间对这个指令的改变都将被忽略,但对MaxClients
的修改却会生效。
使用这个指令时要特别当心。如果将ServerLimit
设置成一个高出实际需要许多的值,将会有过多的共享内存被分配。如果将ServerLimit
和MaxClients
设置成超过系统的处理能力,Apache可能无法启动,或者系统将变得不稳定。
对于prefork
MPM,只有在你需要将MaxClients
设置成高于默认值256的时候才需要使用这个指令。要将此指令的值保持和MaxClients
一样。
对于worker
MPM,只有在你需要将MaxClients
和ThreadsPerChild
设置成需要超过默认值16个子进程的时候才需要使用这个指令。不要将该指令的值设置的比MaxClients
和ThreadsPerChild
需要的子进程数量高。
注意
Apache在编译时内部有一个硬限制"ServerLimit 20000
"(对于prefork
MPM为"ServerLimit 200000
")。你不能超越这个限制。
参见
- 停止和重启Apache
StartServers 指令
说明 | 服务器启动时建立的子进程数 |
---|---|
语法 | StartServers number |
默认值 | 参见下面的说明 |
作用域 | server config |
状态 | MPM |
模块 |
mpmt_os2 , prefork , worker
|
StartServers
指令设置了服务器启动时建立的子进程数量。因为子进程数量动态的取决于负载的轻重,所有一般没有必要调整这个参数。
不同的MPM默认值也不一样。对于worker
默认值是"3
"。对于prefork
默认值是"5
",mpmt_os2
是"2
"。
StartThreads 指令
说明 | 服务器启动时建立的线程数 |
---|---|
语法 | StartThreads number |
默认值 | 参见下面的说明 |
作用域 | server config |
状态 | MPM |
模块 |
beos , mpm_netware
|
设置了服务器启动时建立的线程数量。因为线程数量动态的取决于负载的轻重,所有一般没有必要调整这个参数。
对于mpm_netware
,默认值是"50
",由于只有一个进程,因此所有的线程都将用于伺服请求。
对于beos
,默认值是"10
",同样也是所有的线程都将用于伺服请求。
ThreadLimit 指令
说明 | 每个子进程可配置的线程数上限 |
---|---|
语法 | ThreadLimit number |
默认值 | 参见下面的说明 |
作用域 | server config |
状态 | MPM |
模块 |
mpm_winnt , worker
|
兼容性 | 仅用于2.0.41及以后版本的mpm_winnt
|
这个指令设置了每个子进程可配置的线程数ThreadsPerChild
上限。任何在重启期间对这个指令的改变都将被忽略,但对ThreadsPerChild
的修改却会生效。
使用这个指令时要特别当心。如果将ThreadLimit
设置成一个高出ThreadsPerChild
实际需要很多的值,将会有过多的共享内存被分配。如果将ThreadLimit
和ThreadsPerChild
设置成超过系统的处理能力,Apache可能无法启动,或者系统将变得不稳定。该指令的值应当和ThreadsPerChild
可能达到的最大值保持一致。
对于mpm_winnt
,ThreadLimit
的默认值是1920
;对于其他MPM这个值是64
。
注意
Apache在编译时内部有一个硬性的限制"ThreadLimit 20000
"(对于mpm_winnt
是"ThreadLimit 15000
"),你不能超越这个限制。
ThreadsPerChild 指令
说明 | 每个子进程建立的线程数 |
---|---|
语法 | ThreadsPerChild number |
默认值 | 参见下面的说明 |
作用域 | server config |
状态 | MPM |
模块 |
mpm_winnt , worker
|
这个指令设置了每个子进程建立的线程数。子进程在启动时建立这些线程后就不再建立新的线程了。如果使用一个类似于mpm_winnt
只有一个子进程的MPM,这个数值要足够大,以便可以处理可能的请求高峰。如果使用一个类似于worker
有多个子进程的MPM,每个子进程所拥有的所有线程的总数要足够大,以便可以处理可能的请求高峰。
对于mpm_winnt
,ThreadsPerChild
的默认值是64
;对于其他MPM是25
。
ThreadStackSize 指令
说明 | 处理客户端连接的线程使用的栈尺寸(字节) |
---|---|
语法 | ThreadStackSize size |
默认值 | NetWare上为65536;其它平台上等于操作系统默认值 |
作用域 | server config |
状态 | MPM |
模块 |
mpm_netware , mpm_winnt , worker
|
兼容性 | 仅在 Apache 2.1 及以后的版本中可用 |
ThreadStackSize
指令设置了处理客户端连接(包括调用模块以协助处理)的线程允许使用的最大栈尺寸(字节)。在大多数情况下,操作系统默认的栈尺寸很合理,但是在某些情况下,需要调整这个值:
- 在默认栈尺寸较小的平台上(比如HP-UX),Apache可能会在使用一些需要较大栈尺寸的第三方模块时崩溃。这样的问题可以通过将
ThreadStackSize
设置为一个较大的值来解决。这种调整应当仅仅在第三方模块提供者明确要求的情况下才需要,或者是您通过诊断确定是由于栈空间太小而导致崩溃。 - 在某些平台上,如果默认的栈空间大于服务器运行所需空间,那么将
ThreadStackSize
值降低到小于操作系统默认值可以让每个进程中允许生成的最大线程数量增加。这种类型的调整应该仅在测试环境中使用,并且对所有服务器进程进行充分的测试,因为处理某些罕见的请求需要较大的栈空间。一个很小的服务器配置变化就有可能使得当前的ThreadStackSize
设置变得不合适。
User 指令
说明 | 实际服务于请求的子进程运行时的用户 |
---|---|
语法 | User unix-userid |
默认值 | User #-1 |
作用域 | server config |
状态 | MPM |
模块 |
prefork , worker
|
兼容性 | 2.0版本起仅在全局服务器配置中可用 |
User
指令用于设置实际提供服务的子进程的用户。为了使用这个指令,服务器必须以root
身份启动和初始化。如果你以非root
身份启动服务器,子进程将不能够切换至非特权用户,并继续以启动服务器的原始用户身份运行。如果确实以root
用户启动了服务器,那么父进程将仍然以root
身份运行。Unix-userid是下列值之一:
- 一个用户名
- 通过用户名引用用户
- "#"号后面跟一个用户编号
- 通过用户编号引用用户
用于运行子进程的用户必须是一个没有特权的用户,这样才能保证子进程无权访问那些不想为外界所知的文件,同样的,该用户亦需没有执行那些不应当被外界执行的程序的权限。强烈推荐你专门为Apache子进程建立一个单独的用户和组。一些管理员使用nobody
用户,但是这并不能总是符合要求,因为可能有其他程序也在使用这个用户。
安全
不要将User
(或Group
)设置成root
,除非你明确知道自己在做什么,并且明白其风险所在。
特别提示:在<VirtualHost>
段中使用该指令已经不再被支持了。你可以使用suexec
的SuexecUserGroup
指令来达到这个目的。
注意
虽然User
指令也存在于beos
和mpmt_os2
MPM中,但是事实上没用任何用处,只不过是个摆饰罢了。