ruby - Ruby 中的进程间信号处理

标签 ruby ipc signals system-calls

我运行这个脚本:

t = fork do
  Signal.trap "INT" do
    puts "child"
    exit
  end

  sleep 10
end


Signal.trap "INT" do
  puts "parent"
  Process.kill "INT", t
  Process.waitpid t  
  exit
end

Process.waitpid t

当我按 CTRL+C 时,我得到了

$ ruby sigtest.rb 
^Cchild 
parent

您可以看到“INT”传递给了每个进程,Process.kill "INT", t 尝试杀死已经死亡的进程。有没有办法让用户 INT 信号只传递给 parent ?输出将是:

$ ruby sigtest.rb 
^Cparent
child

解决方案

规则:

  • When you press ctrl+c, SIGINT is passed to whole process group.
  • When you fork new process, signal handlers are not passed to new process

所以如果你想手动控制子进程信号,你必须改变进程的GID。

  def system cmd
    pid = fork do
     exec cmd, {:pgroup => true}
    end

    Process.wait pid
    $?.success?
  end

  def ` cmd # `make syntax highlight happy

    readme, writeme = IO.pipe
    pid = fork do
      $stdout.reopen writeme
      readme.close
      exec cmd, {:pgroup => true}
    end

    writeme.close
    data = readme.read

    Process.wait pid

    data
  end

最佳答案

您总是可以让 child 忽略 INT 信号。

关于ruby - Ruby 中的进程间信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6927993/

相关文章:

ruby - 导轨 4 : Additional form field

c - 信号——c99 与 gnu99

c - 如何解决 "msgget: No space left on device"错误?

c++ - 调试和自由执行中的信号处理

c - Linux 如何确定自定义信号处理程序的优先级?

Ruby 2.0 iconv 替换

php - 从 Ruby 调用 PHP 并获取响应

ruby - 没有 Rails 的 Sidekiq 不会加载工作类

c# - 使用 C# 在同一进程中使用 IPC 管道

c# - 保存应可从不同应用程序/进程访问的临时数据的最佳实践