I want to create a copy the RAM used by a certain program to a file. And then restore that state again later.
Заблуждение :процесс имеет свое виртуальное адресное пространство и использует виртуальную память . Оперативная память сама по себе является ресурсом, которым управляет ядро ОС. ЧтениеОперационная система :Three Easy Pieces(процесс не использует напрямую ОЗУ ).
(вам лучше отредактировать и улучшить свой вопрос, чтобы объяснить гораздо больше об этом :какую программу вы имеете в виду, в каком контексте, почему, на какое время вам нужно "остановить" программа, нужно ли потом перезапускать улучшенную версию...? без этих деталей мы не можем помочь намного больше.)
В Linux можно использовать proc (5)для запроса виртуального адресного пространства некоторого заданного процесса. Попробуйте
cat /proc/$$/maps
иcat /proc/self/maps
I also want to free the RAM
В этом нет необходимости, так как ядро управляет оперативной памятью (иногда может происходить перегрузка ). См. также madvise (2 ), posix _fadvise (2 ), mmap (2 ), mlock (2). Когда процесс завершается, ядро освобождает свое виртуальное адресное пространство, а затем повторно использует выделенную для него оперативную память. Когда процесс останавливается (, например. через Ctrl Z отправку
SIGTSTP
, см. сигнал (7)и termios (3 )), ядро может повторно использовать свою оперативную память для других целей (и используйте пространство подкачки для хранения грязных страниц -, т.е. выходных страниц-этого остановленного процесса ).Прочтите о пейджинге по требованию и http://linuxatemyram.com/.
То, что вам нужно, связано сконтрольными точками приложенияи ортогональным сохранением. В Unix и Linux (и большинстве других операционных систем, включая Windows, Android, MacOSX,... )это невозможно или очень сложновообще(как бы вы справились открытые файловые дескрипторы , дочерние процессы , сокеты , ASLR , семафоры , потоки , блокировка файлов , графические пользовательские интерфейсы , разделяемые библиотеки и т. д... ). Но вы можете написать приложение с такой функцией (, и вы можете найти библиотеки, помогающие в этом ); конечно, вы будете следовать некоторым дополнительным соглашениям и ограничениям, чтобы сделать постоянство или контрольные точки осуществимыми и практичными.
Если вы хотите, чтобы система -была широкой, рассмотрите гибернацию .
Персистентность — это то, о чем нужно подумать на самом раннем этапе разработки вашего приложения (и может быть сложно добавить впоследствии ). Обратите внимание, что базы данных(sqlite , СУБД , nosql базы данных,... )и индексированные файлы(gdbm ... )можно рассматривать как обычный способ достижения некоторой сохраняемости (вы можете рассматривать свою кучу как циклический граф объектов ). Сохраняющийся код -связанные данные (например. классы , vtables , замыкания , указатели на функции ... )в общем сложно.
Вы можете найти некоторые библиотеки для создания контрольных точек , например. BLCR или CRIU . Конечно, они работают в ограниченном контексте приложений, разработанных для их использования.
Наконец, с алгоритмической точки зрения,сохранение всего состояния (или его контрольная точка )очень близко к точному копированию сборщиков мусора . Итак, читая что-то о них, например. полезно руководство GC .
Тем не менее, подлинную сохраняемость или контрольные точки трудно реализовать, и их следует учитывать на раннем этапе разработки приложения. Во многих случаях достаточно сложно потребовать полной перезаписи приложения , не обеспечивающего его.
Оставаться совместимым с эволюцией кода еще сложнее (например. возможность перезапустить с более новой версией вашего кода, примененной к старой контрольной точке ). Вас могут вдохновить методы динамического обновления программного обеспечения .
Некоторые реализации языков программирования (, например. Ocaml, Python, Java,... )предоставляют средства сериализации или сортировки , которые могут помочь. У других есть способ поставить контрольную точку (, например. SBCL
save-lisp-and-die
, PolyMLexport
). Homoiconicity и отражение — полезные функции языка программирования.См. также RefPerSys и Bismon в качестве примеров постоянных систем.
Вы неправильно используете оператор по модулю.
echo 0 62 | awk '{ print $1 % $2 }' # "0"
echo 1 62 | awk '{ print $1 % $2 }' # "1"
echo 61 62 | awk '{ print $1 % $2 }' # "61"
echo 62 62 | awk '{ print $1 % $2 }' # "0" not "62"
Ваш z
является 62-м символом строки charset
. Вы вычисляете смещения по модулю 62, что означает, что ваши результирующие значения могут быть в диапазоне 0
... 61
. Поскольку awk
ожидает строковых смещений от 1
, вам нужно добавить 1
к полученному значению, чтобы вычислить смещение так, чтобы оно находилось в диапазоне 1
... 62
:
newch = substr(charset, ( (i+key)%62 )+1, 1)
Функция substr()
выбирает подстроку из строки. Позиция, указанная в качестве второго аргумента, отсчитывается от 1, а не от 0, в то время как оператор модуля, используемый как %62
, даст вам целые числа от 0 до 61.
Это означает, что вам придется изменить вызов substr()
на
newch = substr(charset, 1 + ((i + key)%62), 1)
В качестве альтернативы, чтобы избежать магических констант,
newch = substr(charset, 1 + ((i + key)%length(charset)), 1)