R 控制台可以支持后台任务或中断(事件处理)吗?
在 R 控制台中工作时,我想设置一个后台任务来监视特定连接,并在发生事件时执行另一个函数(警报)。或者,我可以进行设置,以便外部函数仅向 R 发送警报,但这似乎是同一个问题:有必要设置一个侦听器。
我可以在 R 的专用进程中执行此操作,但我不知道这在控制台中是否可行。另外,如果 R 正在计算函数,我对中断 R 不感兴趣,但如果控制台只是等待输入,则发出警报或中断。
以下是三个用例:
最简单的示例是查看文件。假设我有一个名为“latestData.csv”的文件,并且我想监视它的更改;当它发生变化时,
myAlert()
就会被执行。 (可以扩展它来执行不同的操作,但只是弹出文件已更改的注释就很有用。)另一种监视器会监视给定计算机是否运行内存不足并可能执行
save.image()
并终止。同样,这可能是一个简单的问题,即监视外部监视器生成的文件,该文件保存top
或其他命令的输出。一个不同的例子就像另一个最近的SO问题,关于:让 R 停止正在运行的 EC2 机器。如果来自另一台机器或进程的警报告诉程序保存&终止,然后能够监听该警报会很棒。
目前,我怀疑有两种方法可以处理这个问题:通过 Rserve 和可能通过 fork
。如果有人有如何使用包或通过其他方法执行此操作的示例,那就太好了。我认为解决这三个用例中的任何一个都可以解决所有这些用例,对一点外部代码进行取模。
注 2:对于那些熟悉事件处理/事件方法的人来说,这也可以解决所有问题。我只是在 R 中没有找到任何有关此内容的内容。
更新 1:我发现编写 R 扩展的手册 有一个引用事件处理的部分,其中提到了 R_PolledEvents
的使用。这看起来很有希望。
While working in an R console, I'd like to set up a background task that monitors a particular connection and when an event occurs, another function (an alert) is executed. Alternatively, I can set things up so that an external function simply sends an alert to R, but this seems to be the same problem: it is necessary to set up a listener.
I can do this in a dedicated process of R, but I don't know if this is feasible from within a console. Also, I'm not interested in interrupting R if it is calculating a function, but alerting or interrupting if the console is merely waiting on input.
Here are three use cases:
The simplest possible example is watching a file. Suppose that I have a file called "latestData.csv" and I want to monitor it for changes; when it changes,
myAlert()
is executed. (One can extend it to do different things, but just popping up with a note that a file has changed is useful.)A different kind of monitor would watch for whether a given machine is running low on RAM and might execute a
save.image()
and terminate. Again, this could be a simple issue of watching a file produced by an external monitor that saves the output oftop
or some other command.A different example is like another recent SO question, about : have R halt the EC2 machine it's running on. If an alert from another machine or process tells the program to save & terminate, then being able to listen for that alert would be great.
At the moment, I suspect there are two ways of handling this: via Rserve and possibly via fork
. If anyone has examples of how to do this with either package or via another method, that would be great. I think that solving any of these three use cases would solve all of them, modulo a little bit external code.
Note 1: I realize, per this answer to another SO question that R is single threaded, which is why I suspect fork
and Rserve may work. However, I'm not sure about feasibility if one is interfacing with an R terminal. Although R's REPL is attached to the input from the console, I am trying to either get around this or mimic it, which is where fork
or Rserve
may be the answer.
Note 2: For those familiar with event handling / eventing methods, that would solve everything, too. I've just not found anything about this in R.
Update 1: I've found that the manual for writing R extensions has a section referencing event handling, which mentions the use of R_PolledEvents
. This looks promising.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
另一种选择是 svSocket 包。它是非阻塞的。
这是一个使用它的 8 分钟视频,观看次数超过 3,000 次。它展示了如何将 R 会话转变为服务器以及如何向其发送命令并接收返回的数据。它演示了即使服务器繁忙时也可以这样做;例如,假设您启动了一个长时间运行的进程并忘记保存中间结果,您可以连接到服务器并从中获取结果(在完成之前)。
One more option is the svSocket package. It is non blocking.
Here is an 8 minute video using it, which has over 3,000 views. It shows how to turn an R session into a server and how to send commands to it and receive data back. It demonstrates doing that even while the server is busy; e.g., say you start a long running process and forget to save intermediate results, you can connect to the server and fetch the results (before it has finished) from it.
这取决于您是否想要中断空闲或工作的 R。如果是第一个,您可以考虑通过某些事件侦听器绕过 R 默认 REPL 循环,该事件侦听器将对传入事件进行排队并评估它们。常见的选项是使用 tcl/tk 或 gtk 循环;我在我的 triggr 包中围绕 libev 做了类似的事情,这使得 R 摘要来自套接字的请求。
后一种情况基本上是没有希望的,除非您手动编写计算代码来定期执行
if(evenOccured) processIt
代码。多线程不是一个真正的选择,因为正如您所知,一个进程中的两个解释器将通过使用相同的全局变量来破坏自身,而分叉进程将具有独立的内存内容。
It depends whether you want to interrupt idling or working R. If the first, you can think of bypassing the R default REPL loop by some event listener that will queue the incoming events and evaluate them. The common option is to use tcl/tk or gtk loop; I have made something like this around libev in my triggr package, which makes R digest requests coming from a socket.
The latter case is mostly hopeless, unless you will manually make the computational code to execute
if(evenOccured) processIt
code periodically.Multithreading is not a real option, because as you know two interpreters in one process will break themselves by using same global variables, while forked processes will have independent memory contents.
事实证明,
Rdsm
包也支持这一点。通过这个包,我们可以在不同的R实例之间建立服务器/客户端关系,每个实例都是一个基本的R终端,服务器可以向客户端发送消息,包括函数。
转换为我描述的用例,服务器进程可以执行任何必要的监视,然后向客户端发送消息。不幸的是,该文档有点简洁,但功能似乎很简单。
例如,如果服务器进程定期监视连接(文件、管道、URL 等)并且遇到触发器,则它可以向客户端发送消息。
尽管该包的主要目的是共享内存(这就是我遇到它的方式),但此消息传递对于其他目的也非常有效。
更新 1:当然,对于消息传递,不能忽视 MPI 和
Rmpi
包。这也许能解决问题,但是 Rdsm 包启动/与 R 控制台一起工作,这正是我想要的界面。我还不确定Rmpi
支持什么。It turns out that the package
Rdsm
supports this as well.With this package, one can set up a server/client relationship between different instances of R, each is a basic R terminal, and the server can send messages, including functions, to the clients.
Transformed to the use case I described, the server process can do whatever monitoring is necessary, and then send messages to the clients. The documentation is a little terse, unfortunately, but the functionality seems to be straightforward.
If the server process is, say, monitoring a connection (a file, a pipe, a URL, etc.) on a regular basis and a trigger is encountered, it can then send a message to the clients.
Although the primary purpose of the package is shared memory (which is how I came across it), this messaging works pretty well for other purposes, too.
Update 1: Of course for message passing, one can't ignore MPI and the
Rmpi
package. That may do the trick, but theRdsm
package launches / works with R consoles, which is the kind of interface I'd sought. I'm not yet sure whatRmpi
supports.一些想法:
从另一种语言的脚本中运行 R(这是可能的,例如,在 Perl 中使用 RSPerl )并使用包装脚本来启动侦听器。
另一个选项可能是从 R 内部运行外部(非 R)命令(使用
system()
),这将在后台启动侦听器。启动 R 之前或在单独的窗口中在后台以批处理模式运行 R。
例如:
<块引用>
R --不保存 <监听器.R>输出.out &
事件发生时,侦听器可以发送适当的电子邮件。
A few ideas:
Run R from within another language's script (this is possible, for example, in Perl using RSPerl) and use the wrapping script to launch the listener.
Another option may be to run an external (non-R) command (using
system()
) from within R that will launch a listener in the background.Running R in batch mode in the background either before launching R or in a separate window.
For example:
The listener can send an approraite email when the event occurs.