4

このコードを書いて、プロセスをデーモンで実行しました。目標は、親を閉じてもこのプロセスを実行することです。さて、標準入力に何かを書き込めるようにしたいと思います。私は何をすべきか ?これがコードです。

def daemonize(cmd, options = {})
  rd, wr = IO.pipe
  p1 = Process.fork {
    Process.setsid
    p2 = Process.fork {
      $0 =  cmd #Name of the command
      pidfile = File.new(options[:pid_file], 'w')
      pidfile.chmod( 0644 )
      pidfile.puts "#{Process.pid}"
      pidfile.close
      Dir.chdir(ENV["PWD"] = options[:working_dir].to_s) if options[:working_dir]
      File.umask 0000
      STDIN.reopen '/dev/null'
      STDOUT.reopen '/dev/null', 'a'
      STDERR.reopen STDOUT
      Signal.trap("USR1") do
        Console.show 'I just received a USR1', 'warning'
      end
      ::Kernel.exec(*Shellwords.shellwords(cmd)) #Executing the command in the parent process
      exit
    }
    raise 'Fork failed!' if p2 == -1
    Process.detach(p2) # divorce p2 from parent process (p1)
    rd.close
    wr.write p2
    wr.close
    exit
  }
  raise 'Fork failed!' if p1 == -1
  Process.detach(p1) # divorce p1 from parent process (shell)
  wr.close
  daemon_id = rd.read.to_i
  rd.close
  daemon_id
end

/dev/null の代わりにパイプのようなもので標準入力を再度開く方法はありますか?

4

1 に答える 1

2

fifoはどうですか?mkfifoLinux では、次のコマンドを使用できます。

$ mkfifo /tmp/mypipe

次に、そのパイプで STDIN を再度開くことができます。

STDIN.reopen '/tmp/mypipe'
# Do read-y things

他のものはそのパイプに書き込むことができます:

$ echo "roflcopter" > /tmp/mypipe

そのデータを ruby​​ プロセスで読み取れるようにします。

(更新) ブロックに関する警告

fifos は読み取りと書き込みが発生するまでブロックするため (たとえば、書き込みがなければ読み取りはブロックされ、その逆も同様)、複数のスレッドで処理するのが最適です。1 つのスレッドが読み取りを行い、データをキューに渡し、別のスレッドがその入力を処理する必要があります。その状況の例を次に示します。

require 'thread'

input = Queue.new
threads = []

# Read from the fifo and add to an input queue (glorified array)
threads << Thread.new(input) do |ip|
  STDIN.reopen 'mypipe'
  loop do
    if line = STDIN.gets
      puts "Read: #{line}"
      ip.push line
    end
  end
end

# Handle the input passed by the reader thread
threads << Thread.new(input) do |ip|
  loop do
    puts "Ouput: #{ip.pop}"
  end
end

threads.map(&:join)
于 2013-08-12T12:49:02.550 に答える