我有一個使用C++編寫的舊應用程序,我正在將它移植到Ruby中。如何在Ruby中模仿execl()
代碼的一部分使用execl()
,以便在維護打開的文件描述符(此應用程序是網絡服務)的同時用自身的[n更新]副本替換進程。
if (execl("./my-app", "-restart", fd.c_str(), NULL) < 0) {
沒多久弄清楚,Ruby沒有execl()
相當,但你可以僞造它使用Process::spawn
和:close_others
選項的一部分。或者,至少我應該能夠根據documentation:
文件描述符繼承:關閉非重定向非標準FDS(3,4,5,...)或不 :close_others =>真:不繼承
所以,在我看來,以下應該釀出具有訪問父的所有打開的文件描述符的新工藝:
server_fd = @server.to_i
env = {
"APP_REBOOT" => "true",
"APP_SERVER_FD" => server_fd.to_s,
}
command = "ruby my-app.rb"
options = {
:in => :in,
:out => :out,
:err => :err,
:close_others => false,
}
pid = Process.spawn env, command, options
Process.detach pid
,這將使孩子訪問描述符... ho wever我不知道如何exit
父進程沒有關閉所有的描述符。換句話說,如果我引起家長exit
的代碼的末尾:
server_fd = @server.to_i
env = {
"APP_REBOOT" => "true",
"APP_SERVER_FD" => server_fd.to_s,
}
command = "ruby my-app.rb"
options = {
:in => :in,
:out => :out,
:err => :err,
:close_others => false,
}
pid = Process.spawn env, command, options
Process.detach pid
exit # ADDED THIS LINE
然後描述符也被關閉了的孩子。
我有一種感覺,這是我的過程管理方法比Ruby特有的更多的問題,但我沒有看到我做錯了什麼。
$ ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux]
EDIT1 就在我的呼籲Process.spawn
(或Process.exec
作爲@mata指出)我有一個診斷輸出:
system 'lsof -c ruby'
而另一個呼叫到就在我的recover_from_reboot
方法裏面。這是輸出預重啓的尾巴,你可以看到最後兩行監聽服務器端口和連接的客戶端:
ruby 8957 chris 0u CHR 136,1 0t0 4 /dev/pts/1
ruby 8957 chris 1u CHR 136,1 0t0 4 /dev/pts/1
ruby 8957 chris 2u CHR 136,1 0t0 4 /dev/pts/1
ruby 8957 chris 3r FIFO 0,8 0t0 12213372 pipe
ruby 8957 chris 4w FIFO 0,8 0t0 12213372 pipe
ruby 8957 chris 5r FIFO 0,8 0t0 12213373 pipe
ruby 8957 chris 6w FIFO 0,8 0t0 12213373 pipe
ruby 8957 chris 7u IPv4 12213374 0t0 TCP localhost.localdomain:boks-servc (LISTEN)
ruby 8957 chris 8u IPv4 12213423 0t0 TCP localhost.localdomain:boks-servc->localhost.localdomain:45249 (ESTABLISHED)
這是我看到後重啓:
ruby 8957 chris 3r FIFO 0,8 0t0 12203947 pipe
ruby 8957 chris 4w FIFO 0,8 0t0 12203947 pipe
ruby 8957 chris 5r FIFO 0,8 0t0 12203948 pipe
ruby 8957 chris 6w FIFO 0,8 0t0 12203948 pipe
再次,這是我是否嘗試spawn
或exec
。
EDIT2 鑑於我的診斷輸出,我看到了從服務器不斷結合的fd 7,和客戶端8。通過添加
7 => 7,
8 => 8,
我options
陣列,我能夠使用exec
堅持成功在重新引導這些插座。我可以手動添加服務器和[client1, client2,...]
fd
s到選項散列,但這看起來很髒,當:close_others
應該爲我做繁重的工作。
爲什麼不只是使用['exec'](http://ruby-doc.org/core-2.1.1/Process.html#method-c-exec)?它可以完成'execl'在C中所做的一切... – mata
好的電話@mata,不幸的是我仍然看到相同的結果。 –