2016-02-06 11 views
8

Ruby's callcc przechwytuje bieżącą kontynuację, którą można później wywołać w celu przywrócenia kontroli, ale nie danych. Chciałbym uchwycić obecną kontynuację wraz z obecnym obrazem pamięci.Punkt kontrolny i przywracanie sterty w Ruby

Wydaje mi się, że chwytanie sterty nie powinno być trudne; Mogę polegać na ObjectSpace::each_object i ObjectSpace::dump_all lub Marshal.dump lub po prostu Object.clone. Jednak nie widzę żadnego prostego sposobu na przywrócenie sterty. Idealnie, chciałbym przemieścić mapę object_id -> object, przywracając stary obraz obiektu dla każdego object_id (i ponownie dodając object_id, jeśli odpowiedni obiekt został GC'd). Nic dziwnego, że nie ma api poziomów na poziomie Ruby, który pozwala mi to zrobić. Zastanawiam się, czy są jakieś haki niskopoziomowe do GC Rubiego, z których mogę korzystać.

Każda pomoc jest doceniana, w tym sugestie dotyczące alternatywnych podejść.

Odpowiedz

1

Aby odpowiedzieć na moje własne pytanie, Process.fork mogą być wykorzystane do bardziej lub mniej osiągnąć efekt sterty punktów kontrolnych i renowacji. Ilekroć muszę kontrolować stertę, rozwidłuję nowy proces i pozwalam dziecku kontynuować. Proces rodzic zawiera teraz checkpointed sterty:

def checkpoint 
    if Process.fork.nil? then # if child, then resume execution immediately 
    return 
    else # if parent, wait for the child to exit. 
    Process.wait 
    end 
    return # Parent now resumes execution from state it was in before forking. 
end 

Kiedy musi zostać przywrócony stan, proces dziecko po prostu opuszczającego:

def restore 
    Process.exit 
end 

Obecnie używam tego rozwiązania, a nie napotkał żadnych problemów tak daleko. Zmienię tę odpowiedź, jeśli znajdę jakąkolwiek w przyszłości.