ruby 1.7 特性
由Process.wait等生成的对象。用来表示进程的终止状态(status)。
self == other若状态值相同则返回真。
若other是数值,则先self.to_i,然后再进行比较。这可以解决后续兼容问题。
self & other等同于to_i & other。
该方法是为了解决后续兼容问题而设置的。
pid返回已终止的进程的进程ID。
to_i返回C语言中的终止状态的整数值。
在大部分系统中,该值的高8bit中保存的是传给exit(2)的终止状态值,而低8bit中保存的是诸如信号(signal)引起了终止等信息。
to_int与to_i相同。该方法使得$?被当作Fixnum来处理(隐式的类型转换)。这主要是为了解决后续的兼容问题。
fork { exit 1 }
Process.wait
p $? # => 256
to_s与to_i.to_s相同。
exited?进程因exit(2)而自我终结(并非被其他进程扼杀)时返回真。
exitstatus若exited?为真则返回进程所返回的终止状态的整数值;除此以外返回nil。
inspect ((<ruby 1.8 特性>))以下列格式输出进程的状态。
正常终止时 #<Process::Status: pid=18262,exited(nnn)> 因信号(signal)而挂起时 #<Process::Status: pid=18262,stopped(SIGxxx=nnn)> 因信号而终止时 #<Process::Status: pid=18262,signaled(SIGxxx=nnn)> (主存储器)信息转储时(该状态值的显示形式取决于所用的系统) #<Process::Status: pid=18262,coredumped>
stopped?若进程处于挂起(未终结)状态时返回真。只有给Process.waitpid设置了Process::WUNTRACED标识时,其结果才会为真。
stopsig若stopped?为真则返回信号(signal)的号码;除此之外返回nil。
signaled?若进程收到一个尚未定义处理程序的信号而终止的话,就返回真。
termsig若signaled?为真则返回扼杀进程的信号的号码;除此之外返回nil。
coredump?若终结时进行了(主存储器)信息转储的话,就返回真。
(该方法需要系统支持。若某平台不支持该方法的话,通常返回false)
使用wait的例子
fork { exit }
Process.wait
case
when $?.signaled?
p "child #{$?.pid} was killed by signal #{$?.termsig}"
when $?.stopped?
# 实际上并未使用 Process.wait,所以不会进行到这里
p "child #{$?.pid} was stopped by signal #{$?.stopsig}"
when $?.exited?
p "child #{$?.pid} exited normaly. status=#{$?.exitstatus}"
when $?.coredump? # 若系统不支持该状态时,通常返回false
p "child #{$?.pid} dumped core."
else
p "unknown status %#x" % $?.to_i
end
对SIGCHLD进行trap的例子
trap(:SIGCHLD) {|sig|
puts "interrupted by signal #{sig} at #{caller[1]}"
# 当众多子进程都终结时,可能只会能收到一个SIGCHLD
# 所以要进行循环
while Process.waitpid(-1, Process::WNOHANG|Process::WUNTRACED)
case
when $?.signaled?
puts " child #{$?.pid} was killed by signal #{$?.termsig}"
when $?.stopped?
puts " child #{$?.pid} was stopped by signal #{$?.stopsig}"
when $?.exited?
puts " child #{$?.pid} exited normaly. status=#{$?.exitstatus}"
when $?.coredump?
puts " child #{$?.pid} dumped core."
else
p "unknown status %#x" % $?.to_i
end
end
}
p pid1 = fork { sleep 1; exit }
p pid2 = fork { loop { sleep } } # 为等待signal而sleep
begin
Process.kill :STOP, pid2
sleep # 为等待SIGCHLD而sleep
Process.kill :CONT, pid2
Process.kill :TERM, pid2
loop { sleep } # 为等待SIGCHLD而sleep
rescue Errno::ECHILD
puts "done"
end
=> 12964
12965
interrupted by signal 17 at -:27:in `sleep'
child 12965 was stopped by signal 19
interrupted by signal 17 at -:30:in `sleep'
child 12965 was killed by signal 15
interrupted by signal 17 at -:30:in `sleep'
child 12964 exited normaly. status=0
done