LINUX.ORG.RU

«sandbox» для объекта

 


1

2

Можно ли в С++ объект заставить использовать только отведённую под него область памяти, чтобы кроме него в эту память никто не мог писать, чтобы потом можно было этот объект скопировать/загрузить обратно вместе со всеми его потрохами (включая содержимое областей памяти, выделенных по указателям)?

★★

Последнее исправление: wstorm (всего исправлений: 3)

Для этого и придумали сериализацию. Пусть объект делает что хочет, но при запросе сольет всё что надо.

FeyFre ★★★★
()

Путаешь тёплое с мягким. Объект - абстракция над размещением данных в памяти, и сам по себе он ничего о своём положении в памяти не знает.

чтобы кроме него в эту память никто не мог писать

Грубо говоря это называется инкапсуляцией, хотя опять же к непосредственно памяти отношения не имеет.

чтобы потом можно было этот объект скопировать/загрузить обратно вместе со всеми его потрохами

[Де]сериализация, но опять же, память нипричём. Если по-сишному можно сделать memset или memcpy для структуры, то в общем случае для инстанса объекта в плюсах это совершенно некорректный подход.

jcd ★★★★★
()
Ответ на: комментарий от jcd

Для этого и придумали сериализацию. Пусть объект делает что хочет, но при запросе сольет всё что надо.

Ну конечно. А для сериализации придумали Boost - Serialization, который работает со всякими непонятными штуками, потому что в общем случае просто так провести сериализацию нельзя.

Путаешь тёплое с мягким. Объект - абстракция над размещением данных в памяти, и сам по себе он ничего о своём положении в памяти не знает.

Объект-то не знает, но я хочу знать. Возможно, нужен другой менеджер памяти, который бы хранил всё в скопом. Я не хочу заставлять пользователей в каждом классе описывать процедуру [де]сериализации, ибо это всё равно печально кончится.

Пока читаю тут:...
http://www.ibm.com/developerworks/aix/tutorials/au-memorymanager/

wstorm ★★
() автор топика
Последнее исправление: wstorm (всего исправлений: 1)

чтобы потом можно было этот объект скопировать

А потом вызвать деструктор, еще раз и OH SHI—

Uter
()

Если речь о произвольном объекте, то нет. Если речь идёт об объекте написанного тобой класса, то почему бы и нет.

KblCb ★★★★★
()
Ответ на: комментарий от wstorm

Всё просто - пишешь свой аллокатор, который инстанцируешь в каждой твоей структуре данных, либо в их множестве.

Далее всё это просто сохраняешь. Но тебе надо либо использовать относительную адресацию - т.е. все указатели у тебя будут не адресами, а оффсетом от начала инстанса хипа. Это даст тебе экономию памяти как профит, длинна инстанса меньше 4-гб.

Далее можно с этим не замарачиваться и использовать mmap - он умет давать тебе конкретные адреса.

Но естественно всё это не работает с крестами, деструкторами и всей этой хернёй. Но если ты сможешь в это - тебе они не понадобятся.

Можешь сохранять контекст с памятью и всё поидее будет работать даже с деструкторами.

registrant27492
()
Ответ на: комментарий от RazrFalcon

Лучше бы написали зачем вам это нужно.

Очевидно он привык к managed языкам и хочет чтобы на крестах было так же.

m0rph ★★★★★
()
Ответ на: комментарий от registrant27492

Да, спасибо. По ссылке выше, на ibm, как раз есть похожий пример.
Хочу сделать ядро для имитационного моделирования, в котором бы была возможность продолжить с сохранённой ранее контрольной точки (а модель напихана блоками, которые пишет непонятно кто). Памяти доступно на два порядка больше чем требуется модели, но, наверное, ещё нужно потеснить ОС, чтобы наверняка оставались в наличии блоки необходимой длины... А ещё можно было бы разделить все блоки на группы, каждая из которых выполнялась бы в своём потоке и имела бы свою область памяти, тогда можно было бы упростить malloc:

Functions such as malloc and new are general-purpose memory allocators. Your code may be single-threaded, but the malloc function it is linked to can handle multithreaded paradigms just as well. It is this extra functionality that degrades the performance of these routines.

wstorm ★★
() автор топика
Последнее исправление: wstorm (всего исправлений: 1)
Ответ на: комментарий от wstorm

... в котором бы была возможность продолжить с сохранённой ранее контрольной точки ...

Для этого можно пользоваться простым fork'ом, не обязательно городить какой-то ад с аллокаторами.

mashina ★★★★★
()
Ответ на: комментарий от mashina

Для этого можно пользоваться простым fork'ом, не обязательно городить какой-то ад с аллокаторами.

Да, действительно =)

wstorm ★★
() автор топика
Ответ на: комментарий от wstorm

ещё нужно потеснить ОС, чтобы наверняка оставались в наличии блоки необходимой длины

Это не нужно, если у тебя тачка 64битная - у тебя есть минимум 256терабайт памяти - в ней какой угодно кусок найдётся всегда. Вся эта память доступна твоему процессу монопольно - там где-то снизу куча на брк, а где-то сверху стек - про это надо почитать, но в целом никаких проблем нет.

Память фрагментироваться не может. Т.е. вся память что есть у тебя может быть связана с любой длинны адресным пространством, ну которой не больше длинны свободной памяти. Всегда.

Хочу сделать ядро для имитационного моделирования, в котором бы была возможность продолжить с сохранённой ранее контрольной точки (а модель напихана блоками, которые пишет непонятно кто).

Ну если тебе надо просто восстанавливать данные в наборе структур, которые есть всегда и управление ими от них не зависит - тут вроде всё очень просто - восстанавливай память и используй их.

Я не эксперт во всех этих С++-делах, но не вижу проблем в том, чтобы сделать что-то void * data = read_from_disk(); move(*(my_class*)data) во все текущие структуры.

registrant27492
()
Ответ на: комментарий от wstorm

А ещё можно было бы разделить все блоки на группы, каждая из которых выполнялась бы в своём потоке и имела бы свою область памяти, тогда можно было бы упростить malloc:

Я не понимаю о чём ты. Зачем это делать?

Functions such as malloc and new are general-purpose memory allocators. Your code may be single-threaded, but the malloc function it is linked to can handle multithreaded paradigms just as well. It is this extra functionality that degrades the performance of these routines.

Ну это понятно зачем - чтобы было по хипу на каждый поток и они не дрались за один хип, но у тебя итак на каждую структуру будут свой хип, либо на блок - что там у тебя.

Без этого ты не сможешь его спокойно сохранить - он у тебя будет натыкан из кусков с разных концов адресспейса.

Но по такой технике твой аллокатор и должен работать - только инстансом у него должен быть не поток, а структура/ы данных.

registrant27492
()

Отмапь область с MAP_FIXED и размещай объекты в ней. Никаких трюков ч оффсетами вместо адресов.

tailgunner ★★★★★
()
Ответ на: комментарий от wstorm

Хочу сделать ядро для имитационного моделирования, в котором бы была возможность продолжить с сохранённой ранее контрольной точки (а модель напихана блоками, которые пишет непонятно кто).

Посмотрите в сторону ООСУБД (вроде objectivity или versant). Помнится, они закрывали большое количество вопросов, с которыми вам доведется столкнуться.

eao197 ★★★★★
()
Ответ на: комментарий от tailgunner

Далее можно с этим не замарачиваться и использовать mmap - он умет давать тебе конкретные адреса.

Действительно. Такой хороший ответ с намёком на не полноценность моего.

registrant27492
()
Ответ на: комментарий от registrant27492

Я не эксперт во всех этих С++-делах, но не вижу проблем в том, чтобы сделать что-то void * data = read_from_disk(); move(*(my_class*)data) во все текущие структуры.

Нее, так не получится, если в структуре есть указатель на выделенный массив, например - его надо дополнительно обрабатывать.

wstorm ★★
() автор топика
Последнее исправление: wstorm (всего исправлений: 1)
Ответ на: комментарий от wstorm

Зачем? Ты уже всё сохранил - у тебя объект есть. Далее ты просто все поля копируешь на место того объекта, который у тебя есть сейчас.

Т.е. ты восстановил этот самый массив в памяти вместе с самим полем-указателем - он есть.

registrant27492
()
Ответ на: комментарий от tailgunner

Мило. Т.е. остальной поток про «оффсеты вместо адресов» ты понял, а про mmap нет? Ну эта такая куллстори конечно. Ладно - ради тебя я в неё поверю.

registrant27492
()
Ответ на: комментарий от eao197

Посмотрите в сторону ООСУБД (вроде objectivity или versant). Помнится, они закрывали большое количество вопросов, с которыми вам доведется столкнуться.

У них там всё закрыто, непонятно, и за доллары.

wstorm ★★
() автор топика
Ответ на: комментарий от wstorm

Объект-то не знает, но я хочу знать.

Не, дядя, минуточку. Ты упомянул, что хочешь сделать некий низкоуровневый хак над стандартными плюсовыми объектами (читай - над стандартным их размещением и работой с памятью). В общем случае - это весьма скользкая дорожка, вызывающая недоумение одним лишь фактом своего существования, посему предлагаю уточнить твой запрос: беря в учёт твои требования, зачем тебе плюсовые классы и возня с их представлениями?

jcd ★★★★★
()
Ответ на: комментарий от wstorm

А ещё можно использовать фичи С++11
https://woboq.com/blog/reflection-in-cpp-and-qt-moc.html
и самому парсить и сериализовать поля класса с учётом их специфики с помощью Boost-Serialization.
...Не получается у меня подключить arrayfire 3.3.2 в проект Qt 5.5.1 - moc ругается. Хорошо будет, если moc в qt6 всё же выпилят. Или использовать CopperSpice...
В arrayfire, кстати, тоже есть свой менеджер памяти: https://github.com/arrayfire/arrayfire/blob/devel/src/backend/MemoryManager.hpp

wstorm ★★
() автор топика
Последнее исправление: wstorm (всего исправлений: 5)
Ответ на: комментарий от wstorm

you can freeze a running application (or part of it) and checkpoint it to a hard drive as a collection of files

Правда, с некоторой стороны очень похоже на fork, т.к. fork тоже по сути может остановить «часть приложения», состоящего из 2 процессов. Но без плюшек.

wstorm ★★
() автор топика
Последнее исправление: wstorm (всего исправлений: 1)

http://en.cppreference.com/w/c/language/restrict — это c99, а не с++ и в с++ нет такого ключевого слова, однако, некоторые компиляторы позволяют использовать его и в с++ (вроде, g++ тоже может, в виде __restrict либо __restrict__)

это штука, которая делает обратную задачу: обещание компилятору, что некоторая память не будет использоваться разными указателями (иногда надо в целях оптимизации). и хотя сам компилятор это дело никак не проверяет, возможно, существуют внешние инструменты, которые позволят проводить автоматическую проверку

next_time ★★★★★
()
Ответ на: комментарий от next_time

Да, компилятор должен радоваться, когда в одном месте памяти читаешь - в другом пишешь.

wstorm ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.