2014-02-15 4 views
0

Я играю с C++ в свободное время. Я совершенно новичок в управлении памятью вручную и многому научился. Я пытаюсь сделать следующее.Указатели C++, к которым обращаются другие приложения

Существует база данных с одной простой таблицей. Я создал консольную прикладную программу C++, которая запускается на сервере приложений и читает содержимое этой таблицы и сохраняет ее в ОЗУ. Затем он записывает адрес памяти в крошечный текстовый файл и переходит в режим сна. Веб-служба выполняется на сервере (на другом сервере, кроме БД, за исключением того же сервера, что и консольное приложение). Некоторые веб-сайты проходят через вызов веб-службы. Вместо того, чтобы ударять базу данных, веб-служба выполняет одну из двух задач. Если веб-сайт делает свой первый запрос, он передает нулевое значение и идентификатор записи, которую он ищет. В этом случае веб-служба считывает адрес из текстового файла и извлекает запись из ОЗУ. Он возвращает запись, а также адрес памяти. Веб-сайт использует запись и помещает адрес памяти в невидимую метку. Следующий вызов, он передает идентификатор нужной записи и адрес памяти. Веб-служба подходит к этому адресу памяти и извлекает запись. Если то, что он находит в этом адресе памяти, не может быть проанализировано в записи, оно проверяет текстовый файл для возможного нового местоположения.

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

ответ

0

Передача указателя из одного процесса в другой для доступа к общей памяти требует наличия общей памяти.

На современном компьютере с современными процессами ОС по умолчанию не используется ни одна память; они имеют отдельные пространства памяти. Указателем, который вы обрабатываете на C++, являются логические адреса, которые автоматически отображаются на основе каждого процесса до физических адресов, используемых аппаратными средствами. Таким образом, значение указателя из процесса A крайне маловероятно для сопоставления с одним и тем же физическим адресом при использовании в процессе B.

Вы можете в принципе реализовать общую память или использовать библиотеку, которая ее реализует, но я советую вместо этого использовать другая форма inter-process communication. В Windows у вас есть множество возможностей, включая сообщение окна WM_DATA, маршалинг по умолчанию сервера COM, почтовые слоты (которые не имеют ничего общего с почтой), общий RPC и т. Д. Для более портативного кода рассмотрите использование сетевых сокетов.

+0

Будет ли межпроцессное общение обладать тем же штрафом, что и вызов отдельного вызова СУБД? Работает ли сборка с прямыми физическими адресами? Возможно, оба приложения могут быть написаны на C++ и использовать встроенную сборку для необходимых частей в отношении адресации. – user3312353

+0

(1) Возможно, это не само по себе, но со всем на месте это может занять больше времени. Единственный способ решить - измерить.(2) Это не тот язык, который определяет, работаете ли вы с логическими или физическими адресами (или с некоторой промежуточной формой: на обычном ПК есть три уровня адресации). Обычные приложения работают с логическими адресами. (3) Обычно оптимизация, выполняемая встроенной сборкой, выполняется для вещей, выполняемых в самых внутренних циклах, что, по-видимому, не является сценарием здесь. Я подозреваю ** преждевременную оптимизацию **, которая, по словам Кнута, просто зла. ;-) –

0

Длинный рассказ короткий. Современная ОС имеет возможность защищать разные процессы от возиться с каждым дополнительным адресным пространством. На самом деле каждый процесс имеет собственное виртуальное адресное пространство, которое ими сопоставляется с физическим адресным пространством ОС. Это означает, что адрес 0x00000001 процесса A и адрес 0x00000001 процесса B не указывает на то же физическое местоположение в ОЗУ.

Таким образом, вы не можете делать то, что вы пытаетесь сделать (простой способ).

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

+0

Помогло бы это, если бы веб-служба изначально написала текстовый файл в предыдущем вызове и поставила этот вызов в режим сна, тем самым сохраняя ОЗУ для последующих вызовов или каждый вызов рассматривался как отдельный процесс? – user3312353

+0

По звонкам я предполагаю, что вы имеете в виду запросы, поступающие на сервер. Я предполагаю, что вы обрабатываете эти запросы в другом потоке. Если это так, вам не нужен текстовый файл вообще, только когда первый запрос приходит, чтобы получить данные в массив или какую-либо другую структуру данных. Храните это в «глобальном» месте (возможно, в глобальном переменном/частном поле и т. Д.). Когда следующий запрос приходит, используйте этот «глобальный» держатель, чтобы получить данные от него. Остерегайтесь нескольких потоков, обращающихся к массиву/держателю одновременно. Вам необходимо реализовать синхронизацию потоков. –

+0

Взгляните на эту статью http://www.bogotobogo.com/cplusplus/multithreaded2B.php –

Смежные вопросы