2014-11-01 12 views
43

Von Hadleys C besten practices:Müssen R-Pakete dynamische Bibliotheken entladen, wenn sie entladen werden?

Wie bei C++, wenn Sie C-Code in Ihrem Paket verwenden, sollten Sie die DLL entladen, wenn das Paket abgeladen wird:

.onUnload <- function (libpath) { 
    library.dynam.unload("mypackage", libpath) 
} 

Writing R Extensions auf der anderen Seite erwähnt dies nicht einmal. Ich kann sehen, wie höflich es wäre, die DLLs zu entladen, aber das zu tun, scheint mir einige seltsame Probleme mit Paketen zu verursachen, die geladen/entladen/neu geladen werden (siehe Beispiel weiter unten). Darüber hinaus gibt es einige Hinweise, die darauf hinweisen, dass ein Entladen nicht erforderlich ist. Von ?library.dynam:

Beachten Sie, dass, ob oder nicht, ist es möglich, eine DLL zu entladen und dann eine überarbeitete Version der gleichen Datei neu zu laden ist OS-abhängig: der ‚Wert‘ Abschnitt der Hilfe für dyn.unload sehen.

obwohl dies nicht Auswirkungen auf Objekte haben sollte, die nicht geändert wurden. Dann gibt es diesen Kommentar von Brian Ripley in R-devel:

Nachdem alles gesagt, dass meine Erfahrung ist, dass die DLL Entladen oft nicht hilft, wenn Sie es erneut laden müssen (und deshalb zB tcltk nicht seine nicht entladen DLL).

Also ist es akzeptabel, die C-Bibliotheken geladen zu lassen? Ich würde es vorziehen, nicht zu wissen, warum Sachen wie das Folgende passieren (geschah nicht, bevor ich anfing, Bibliotheken zu entladen).

R version 3.1.1 (2014-07-10) 
Platform: x86_64-apple-darwin13.1.0 (64-bit) 

> library(alike)  # install_github("brodieg/alike", ref="fdaa578e"), if you're curious 
> library(data.table) 
data.table 1.9.2 For help type: help("data.table") 
> detach("package:data.table", unload=T) 
> detach("package:alike", unload=T) 
> library(alike) 
> library(data.table) 
Error : .onLoad failed in loadNamespace() for 'data.table', details: 
    call: address(x) 
    error: object 'Caddress' not found 
In addition: Warning messages: 
1: In FUN(X[[9L]], ...) : 
    failed to assign RegisteredNativeSymbol for alike to alike since alike is already defined in the ‘data.table’ namespace 
2: In FUN(X[[9L]], ...) : 
    failed to assign RegisteredNativeSymbol for typeof to typeof since typeof is already defined in the ‘data.table’ namespace 
3: In FUN(X[[9L]], ...) : 
    failed to assign RegisteredNativeSymbol for type_alike to type_alike since type_alike is already defined in the ‘data.table’ namespace 
Error: package or namespace load failed for ‘data.table’ 

Die Warnungen beziehen sich alle auf alike Funktionen. alike hat nicht verwendet, um seine dynamischen Bibliotheken zu entladen, und die obigen Fehler sind nicht aufgetreten. Nachdem ich das Entladen implementiert hatte, begannen die Fehler. Beachten Sie, dass data.table 1.9.2 seine DLLs nicht entladen hat, obwohl andere Pakete, die auch DLLs nicht entladen, dieses Problem nicht verursachen. data.table 1.9.4 funktioniert gut.

+0

Ich weiß, es ist deine Frage, aber hast du überhaupt noch zusätzliche Informationen dazu gefunden? – Dason

+0

@Dason, Angst nicht. Ich stieß auch auf [this issue] (https://github.com/Rdatatable/data.table/issues/990) mit "data.table", das möglicherweise verwandt ist oder nicht. Außerdem habe ich dieses Problem seit einer Weile nicht mehr, aber zu viel hat sich geändert, um genau zu wissen, was es behoben hat. – BrodieG

+1

Seltsam.Ich habe die Angewohnheit, automatisch zu entladen, weil ich gebissen wurde, indem ich die falsche Version einer DLL, die ich vergessen habe zu entladen, debuggte. Der Workflow war: Paket laden, Fehler finden, reparieren, Paket neu laden. Aber die DLL wurde nicht entladen. Ews. Der Rat von Hadley ist also hervorragend für Entwickler. Aber ich habe noch nie ein Problem in der Wildnis gesehen. Interessantes Zeug. – Jason

Antwort

3

Normalerweise wäre das Entladen einer DLL eine gute Idee. Die Ressourcen, die es besitzt, würden vollständig freigegeben und ein erneutes Laden wäre kein Problem.

In R gibt es die Komplikation der R-Umgebung, denn selbst wenn eine DLL entladen wird, kann einiges Wissen in der R-Laufzeit übrig bleiben. In diesem Fall kann das Ergebnis sein, dass die neu geladene DLL-Bibliothek nicht denselben abgeleiteten Status wie die R-Variablen hat, die den DLL-Status verstehen sollen, und somit Fehler auftreten.

Ich denke, es wäre möglich, ein R-Paket (DLL und R-Code) sicher zu entladen, aber es wäre einfacher für Sie, die DLLs geladen zu lassen, es sei denn, Sie finden besonders starke Ressourcennutzung.

+0

Ja. Es ist eine sehr schlechte Idee, eine Bibliothek zu entladen, wenn Sie nicht die volle Kontrolle über alle Zeiger auf diese Bibliothek haben. Das Entladen einer Bibliothek ist eine ziemlich ungewöhnliche Operation und viele Programme rufen niemals FreeLibrary() auf. Als Faustregel gilt, dass die Ressourcenzuweisung und -zurückweisung in einem externen Paket wie R in der Verantwortung des Pakets selbst liegt, das nicht ausdrücklich in der Dokumentation angegeben ist. –