also...
wichtig ist, das auslagern nicht als allheilmittel zu sehen. insegsammt muss dadurch ja nicht plötzlich weniger gemacht werden. in den aller meisten fällen ist auch im bezug auf blockieren das auslagern nicht nötig. nonblocking io und select sind sehr mächtig und können sehr viel mehr als die 'modernen' thread befürworter sehen wollen. d.h. es muss aus performance gründen nicht grundsätzlich ausgelagert werden. fhem ist normalerweise nicht durch die rechenleistung begrenz sondern durch io. das auslagern beschleunigt cpu wenn es mehr als einen prozessor (kern) gibt, aber io nur bedingt.
wenn es aus bestimmten gründen (s.u.) doch nötig ist etwas zu parallelisieren oder auzulagern sind (lang laufende) prozesse deutlich einfacher und weniger fehler anfällig als threads.
egal wie dieser externe prozess gestarted wird (fork, exec, perl lesen aus prozess, ...) es ist immer der gleiche grundlegende mechanismus der den neuen prozess erzeugt und dabei potentiell den kompletten speicher dupliziert. d.h. auch: egal ob open($fh, "$cmd|" ) oder explizites fork und exec, unter der haube ist beides identisch! ersteres startet unter umständen sogar noch mehr prozesse weil noch ein shell dazwischen kommt.
in linux sollte eigentlich copy-on-write dafür sorgen das der overhead sich in grenzen hält. ich benutze aktuell kein system bei dem der hauptspeicher so knapp ist das ein fork fehlschlagen würde. daher kann ich hierzu nicht viel sagen.
ebenfalls wichtig: sobald geforkt wurde kann der kind prozess (ausser loggen) nicht mehr auf fhem interne daten zugreifen bzw. erhält nur veraltete versionen. er kann auch direkt keine readings oder anderes mehr aktualisieren. d.h. alles was auswikrungen im 'haupt' fhem haben soll muss irgendwie dorthin kommuniziert werden. der geforkte prozess erhält auch keine events mehr und muss diese anders besorgen wenn er sie braucht!
das forken MUSS mit fhemFork() passieren. sonst werden benutze resource nicht korrekt freigegeben oder geschlossen -> restart schlägt wegen benutzer ports oder usb devices fehl. selbst bei allen vorsichtsmassnahmen bleibt rereadcfg problematisch. aber das ist ein anderes problem und rereadcfg gehört sowieso abgeschafft

.
da ganze ist auch erst mal nicht mit windows installationen kompatibel.
unterm strich: auslagern ist ganz sicher kein muss sondern eine einzelfall entscheidung. wer sich nicht sicher ist was er tut braucht es in der regel nicht. ausser ihm wird ganz konkret das gegenteil bewiesen

.
gründe für das auslagern:
- mehr kern prozessor soll für (aufwändige) berechnungen genutz ausgelastet werden
das trifft für fhem in der regel nicht zu.
- kapseln/stabilität, dafür wäre ein generelles framework tatsächlich schön.
im entwickler bereich gibt es dafür einen uralten proof of concecpt für ein sanboxing
bei dem jeweils keine gruppen von zusammengehörenden modulen in eine eigene sandbox
ausgelagert werden. habe es aber dann doch nicht weiterferfolgt da alle alten module
die direkt auf z.b. {READINGS} zugreifen auf Readings routinen aktualisiert werden müssten.
- es wird eine perl lib verwendet die nur blocking arbeitet oder sich nicht in die fhem select
loop einhängen lässt (1-wire, imap,...)
- es wird ein externes binary verendet. z.b. weil es bereits funktionalität in nicht-perl bibliotheken
gibt die genutz werden sollen. aktuell vor allem node interessant.
- ... ?
BlockingCall: ist hauptsächlich auf nicht besonders häufige und kurze aktionen in perl ausgerichtet.
kommunikation zurück erfolgt über telnet. d.h. ip. daten müssen ascii sein. d.h.
bei kompexeren dingen z.b. json. kein weitere support für loggen, eigene logfiles, ...
SubProcess: hauptsächlich für länger dauernde dinge in perl, kommunikation über explizite descriptoren, ascii oder binär
kein weitere support für loggen, eigene logfiles, ...
CoProcess: hauptsächlich für länger dauernde dinge in einem eigenen prozess der nicht perl sein muss.
kommunikation über stdio. ascii oder binär. bietet support für eigene log files, rotation, ...
unterstützt in verbindung mit dem npmjs modul das aktualiseren externer node libs und
den neu start des moduls danach.