Ruby中的工作控制 - Sigcont处理程序不起作用,SigTSTP处理程序仅适用于IRB。我想念什么?
我正在尝试使用Ruby-gnome中的GliB2 API来为自定义事件循环处理程序实施某种外壳工作控制。理想情况下,这将能够处理sigtstp和sigcont信号,在壳下运行时以tty为背景,并从外壳上恢复“ fg”上的背景过程。
我无法弄清楚如何与Ruby中的API完全处理。
对于更简单的使用情况,我想我会尝试为IRB添加类似的工作支持。我已将以下内容添加到我的〜/.irbrc
中。 SIGTSTP处理程序似乎有效,但是即使在bash中的fg
的Sigcont之后,该过程仍被暂停。
## conditional section for ~/.irbrc
## can be activated with `IRB_JOBS_TEST=Defined irb`
if ENV['IRB_JOBS_TEST']
module Jobs
TSTP_HDLR_ORIG ||= Signal.trap("TSTP") do
STDERR.puts "\nJobs: backgrounding #{Process.pid} (#{TSTP_HDLR_ORIG.inspect}, #{CONT_HDLR_ORIG.inspect})"
Process.setpgid(0, Process.ppid)
TSTP_HDLR_ORIG.call if TSTP_HDLR_ORIG.respond_to?(:call)
end
CONT_HDLR_ORIG ||= Signal.trap("CONT") do
Process.setpgid(0, Process.pid)
STDERR.puts "Continuing in #{Process.pid}" ## not reached, not shown
IRB.CurrentContext.thread.wakeup ## no effect
CONT_HDLR_ORIG.call if CONT_HDLR_ORIG.respond_to?(:call)
end
end
end
我正在freebsd 13.1上测试。我已经阅读了FreeBSD Termios(4),TCSETPGRP(3)和FCNTL(2)手动页面。我不确定Ruby中有多少与终端相关的API。
这里的TSTP处理程序似乎很可行,但显然从未达到过处理程序。我不确定TSTP处理程序实际上是否正在做足够的工作,实际上是 - 在Shell的过程组中背景过程并放弃了控制终端。
使用该TSTP处理程序,我可以使用CTRL-Z在外壳中的IRB过程进行背景。我还可以用“ FG”或Bash'%'来预留该过程,但是该过程没有反应。 FreeBSD的CTL-T
处理程序显示该过程为暂停。显然,我的续处理程序中什么都没有达到。
我真的很喜欢这种方法中的失败 - 我的TSTP/CONT处理程序缺少什么,Ruby中可用的内容以及为什么该过程在外壳中的“ FG”之后悬挂。
在一个更复杂的示例中,使用我为Glib2编写的代码,显然还不足以致电,
Process.setpgid(0, Process.ppid)
因为当时该过程没有被背景。不过,这可能需要另一个问题,因为它的示例代码并不那么简短。因此,我以为我会尝试从IRB开始...
尝试将过程推进过程后,然后在FreeBSD上使用ctrl-t
,我看到以下内容
$ %
IRB_JOBS_TEST=Defined irb
load: 0.16 cmd: ruby31 4076 [suspended] 2.36r 0.19u 0.03s 1% 23828k
mi_switch+0xc2 thread_suspend_check+0x260 sleepq_catch_signals+0x113 sleepq_wait_sig+0x9 _cv_wait_sig+0xec tty_wait_background+0x30d ttydev_ioctl+0x14b devfs_ioctl+0xc6 vn_ioctl+0x1a4 devfs_ioctl_f+0x1e kern_ioctl+0x25b sys_ioctl+0xf1 amd64_syscall+0x10c fast_syscall_common+0xf8
,因此它正在阻止简历上的ioctl?
Update
在对此进行了几个小时的无效黑客攻击之后,我从我的glib示例代码现在,它的“正常工作”。我可以在控制台的示例应用程序中背景一下...至少在IRB下不运行时,我可以将其带回与外壳一起前景。它恢复在Sigcont上运行,并且从其主要事件循环中的日志记录中看起来都还不错。
我仍然不确定丢失的零件可能是什么?当然,随着IRB中的输入历史记录录制通常很简单,可以重新启动该过程。
查看其他应用程序如何在控制台处接近工作控制,我认为Emacs用某种包裹的emacs包装了其TTY I/O流。结构?主要查看Emacs的终端。
很高兴看看Ruby是否有工作控制,甚至不需要某些应用程序的自定义信号处理程序?
I was working on trying to implement some kind of shell job control for a custom event loop handler with the GLib2 API in Ruby-GNOME. Ideally, this would be able to handle SIGTSTP and SIGCONT signals, to background the process at a TTY when running under a shell and to resume the background process on 'fg' from the shell.
I've not been able to figure out how to completely approach this with the API available in Ruby.
For a simpler usage case, I thought that I'd try adding a similar job support for IRB. I've added the following to my ~/.irbrc
. The SIGTSTP handler seems to work, but the process remains suspended even after SIGCONT from fg
in BASH.
## conditional section for ~/.irbrc
## can be activated with `IRB_JOBS_TEST=Defined irb`
if ENV['IRB_JOBS_TEST']
module Jobs
TSTP_HDLR_ORIG ||= Signal.trap("TSTP") do
STDERR.puts "\nJobs: backgrounding #{Process.pid} (#{TSTP_HDLR_ORIG.inspect}, #{CONT_HDLR_ORIG.inspect})"
Process.setpgid(0, Process.ppid)
TSTP_HDLR_ORIG.call if TSTP_HDLR_ORIG.respond_to?(:call)
end
CONT_HDLR_ORIG ||= Signal.trap("CONT") do
Process.setpgid(0, Process.pid)
STDERR.puts "Continuing in #{Process.pid}" ## not reached, not shown
IRB.CurrentContext.thread.wakeup ## no effect
CONT_HDLR_ORIG.call if CONT_HDLR_ORIG.respond_to?(:call)
end
end
end
I'm testing this on FreeBSD 13.1. I've read the FreeBSD termios(4), tcsetpgrp(3), and fcntl(2) manual pages. I'm not sure how much of the terminal-related API is available in Ruby.
The TSTP handler here seems to work, but the CONT handler is apparently not ever reached. I'm not sure if the TSTP handler is actually doing enough for - in effect - backgrounding the process in the shell's process group and relinquishing the controlling terminal.
With that TSTP handler, I can then background the IRB process in the shell with Ctrl-z. I can also foreground the process with 'fg' or BASH '%', but then the process is unresponsive. FreeBSD's Ctl-t
handler shows the process as suspended. Apparently nothing in my CONT handler is reached.
I'm really stumped about what's failing in this approach - what my TSTP/CONT handlers are missing, what's available in Ruby, and why the process stays suspended after 'fg' in the shell.
In a more complex example, with the code I've written for glib2 it was apparently not enough to just call
Process.setpgid(0, Process.ppid)
as the process was not being backgrounded then. This would probably need another question though, as the example code for it isn't quite so short. So, I thought I'd try starting with IRB ...
After trying to foreground the process, then with Ctrl-t
at the TTY on FreeBSD, I'm seeing the following
$ %
IRB_JOBS_TEST=Defined irb
load: 0.16 cmd: ruby31 4076 [suspended] 2.36r 0.19u 0.03s 1% 23828k
mi_switch+0xc2 thread_suspend_check+0x260 sleepq_catch_signals+0x113 sleepq_wait_sig+0x9 _cv_wait_sig+0xec tty_wait_background+0x30d ttydev_ioctl+0x14b devfs_ioctl+0xc6 vn_ioctl+0x1a4 devfs_ioctl_f+0x1e kern_ioctl+0x25b sys_ioctl+0xf1 amd64_syscall+0x10c fast_syscall_common+0xf8
So, it's blocking in an ioctl on resume?
Update
After a few hours of ineffectual hacking about this, I've removed the SIGTSTP and SIGCONT signal handlers from my GLib example code and now it "Just Works". I can background the example app at the console ... at least when it's not running under IRB ... and I can bring it back to the process group foreground with the shell. It resumes running on SIGCONT and everything looks alright in the logging from its main event loop.
I'm still not certain what the missing parts may have been, in may handlers/hacks for SIGTSTP and SIGCONT with IRB. Of course, with the input history recording in IRB it's typically simple enough to just restart the process..
Looking at how other applications have approached job control at the console, I think Emacs wraps its TTY I/O streams in some kind of an encapsulated struct? looking at Emacs' terminal.c mainly.
Glad to see if there's job control available in Ruby though, and it does not even need a custom signal handler for some applications?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论