Process::Status

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