更新R软件包的安全方法 - 可以"热插拔"吗?

Ite*_*tor 8 packages r updates

我曾经遇到过这个问题几次,并且我无法弄清楚任何解决方案,只能解决这个问题(见下文).

假设一台计算机正在运行2个以上的R实例,由于2个用户或1个用户正在运行多个进程,并且有一个实例在执行update.packages().我有好几次,其他的实例可能会被大肆污染.正在更新的软件包不会以任何影响计算的方式更改功能,但不知何故会出现一个大问题.

简单的解决方案(解决方案0)是在update.packages()执行时终止R的所有实例.这有2个问题.首先,必须终止R实例.其次,人们甚至无法确定这些实例的运行位置(请参阅更新1).

假设正在执行的代码的行为不会改变(例如,包更新都是有益的 - 它们只修复错误,提高速度,减少RAM,并授予独角兽),是否有某种方法可以热插拔新版本的包对其他流程的影响较小?

在R之外我还有两个候选解决方案:

解决方案1是使用临时库路径,然后删除旧的旧库并将新库移动到其位置.这样做的缺点是删除+移动可能会产生一些时间,在此期间没有任何可用的东西.

解决方案2是使用符号链接指向库(或库层次结构),并使用指向更新包所在的新库的指针覆盖符号链接.这似乎导致更少的软件包停机时间 - 操作系统覆盖符号链接所需的时间.这样做的缺点是它在管理符号链接时需要更多的关注,并且是特定于平台的.

我怀疑解决方案#1可以通过巧妙的使用来修改为#2,.libPaths()但这似乎不需要调用update.packages(),而是编写一个新的更新程序,找到过时的包,将它们安装到临时库,然后更新库路径.这样做的好处是,可以将现有流程约束到.libPaths()它启动时的流程(即更改R知道的库路径可能不会传播到那些已经运行的实例,而不在该实例中进行一些明确的干预).


更新1.在示例方案中,两个竞争R实例位于同一台计算机上.这不是必需的:据我了解更新,如果两者共享相同的库,即共享驱动器上的相同目录,则更新仍然可能导致问题,即使R的另一个实例在另一台机器上.因此,人们可能会意外地杀死R进程,甚至看不到它.

Jos*_*ien 3

我强烈猜测这是没有办法解决的。

特别是当一个包包含已编译的代码时,您无法删除和替换正在使用的 DLL,并期望它仍然可以工作。R 调用这些函数所使用的所有指向 DLL 的指针都会请求特定的内存位置,并发现它莫名其妙地消失了。(注意——虽然我在这里使用术语“DLL”,但我的意思是在非 Windows 特定的意义上,因为它在例如 . 的帮助文件中使用。?getLoadedDLLs“共享库”可能是更好的通用术语。 )

(我的怀疑来自R for Windows FAQ,其中报告“Windows 在加载时锁定[a]包的 DLL”,这可能会导致update.packages()失败。)

我不确定 R 的延迟加载机制到底是如何实现的,但想象一下,它也可能通过删除它期望在机器中的特定地址找到的对象而被搞乱。

其他对计算机内部结构了解更多的人肯定会给出比这更好的答案,但这些是我的想法。