Longobard
написал 9 января 2006 года в 00:20 (707 просмотров)
Ведет себя
как мужчина; открыл 291 тему в форуме, оставил 2499 комментариев на сайте.
Задача такая:
есть обьект класса X, нужно вызывать его методы из различных процессов. Если вместо процессов использовать треды — то все просто, храним его в памяти процесса и обращаемся к обьекту по указателю из тредов, ибо треды выполняются в том же адресном пространстве, что и процесс, создавший тред.
А как быть в случае с несколькими процессами? Что-то никаких идей нету. Копировать обьект нельзя, он должен быть в единственном экземпляре. Нужно вызвать некоторые методы этого обьекта, в общем иметь к нему доступ. Помогите советом :)
Спасибо :)
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1
ecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.
Определи сегмент shared memory, сообщи его адрес всем процессам и приаатачь. Засунь свой объект в общую память и пользуй изо всех процессов. Больше никак.
Good Luck,
UT
Может быть pipe или socket сойдет?
Как засунуть — понятно (Стивенс есть). А как вызвать метод обьекта, находящегося в общей памяти, без копирования его в память процесса?
Не понял вопроса. Приаттаченный сегмент памяти находится в адресном пространстве всех процессов, которые его приаттачили. Просто вызывай свой метод.
Good Luck,
UT
Моих познаний для ответа на этот вопрос не хватает жутко: как грузиться elf, как g++ оформляет вызов virtual методов, и куча вопросов о shared memory (ну не пользовался я ею не разу) для меня остаются загадкой.
Но попробуй затолкать все объекты которые надо так использовать в libmylib.so, и компоновать приложения с -lmylib. Есть у меня подозрение, что тогда адреса всех функций класса окажутся одинаковыми в обоих процессах, и, может быть, даже будут вызываться без SEGFAULT и прочих сигналов.
Напишу подробнее
хедер: myheader.h
Первый процесс (создающий объект)
Второй процесс должен знать memory id сегмента. Можно получить его при запуске или через pipe/сокет
Второй процесс:
Конечно, надо еще следить, чтобы сегмент не был уничтожен первым процессом, прежде чем второй получит шанс его использовать. Но это уже тонкости…
Good Luck,
UT
угу это работает, но не для виртуальных функций…То есть если myclass::mymethod объявить как virtual оно не работает. Причём я не понял почему :(. Надо будет повтыкать в работу ld.
Uncle Theodore:
Спасибо за подробный ответ!
Но что делать, если (например) обьект является обьектом шаблонного класса? Или же у него есть виртуальные функции, как быть тогда?
что значит шаблонного? если инстанс в памяти есть, и vtable для методов есть, то без разници что за класс. главное что бы ты смог докастить void* до него. а для этого надо что бы сам класс был не абстрактный…
ЗЫ
Или я не понял проблемы?
Скорее всего, проблема в изменении имен функций в С++. Что с этим делать я не знаю, extern «C» запретит оверлоадинг напрочь. Наверное, придется изголяться… Избавляться от виртуальных функций, например.
Good Luck,
UT
не, имена там не причём.
Виртуальные функции не работают не из-за shared memory, и даже не из-за того что методы класса валяются в библиотеке. Ежели память под объект выделять не shmget, а malloc, тот же самый SEGFAULT вылетает. Зато если пользоваться new то всё нормально. То есть, конструкция `*pointer = new myclass;' делает что-то не то. Хотя что, собственно, не то, я так и не понял. Достало разбираться в реализации всех этих virtual call’ов.
В общем, вопрос к знатокам C++, как в C++ можно сказать оператору new, что кусок памяти уже выделен, и его осталось только привести в юзабельный вид. В BorlandC 3.1, такая фича была, как она использовалась не помню. И подозреваю что это было свойством borlandc++, а не c++, но фича была.
new вызывает конструктор. Мне удалось воспроизвести то, о чем ты говоришь (Извиняюсь за длинный пример, но мне было интересно).
Вот так, наверное
new(pointer) concr;
Не думаю, что это фича Борланда, но почему-то не могу найти вразумительной ссылки…
Соответственно, что-то вроде этого надо делать для shmget
Good Luck,
UT
new(pointer) concr; //<-- в g++ это работает.
Но, похоже, что адреса функций таки разные :(. Непонятно, чего это мне вдруг в голову взбрело, что они одинаковые должны быть?
Хотя для не-виртуальных функций работает (это я про shmget и далее). Там система разрешения адресов символов работает. Одна странность осталась: если myclass не в .so класть, а статически линковать, то какие-то аберрации поведения класса наблюдаются :-/