Июнь 16 2010

Использование проекции файла для реализации разделяемой памяти

Самый низкоуровневый механизм совместного использования данных в одной системе — проецирование файла в память. На нем так или иначе базируются все другие механизмы разделения данных. Поэтому, если вы хотите получить максимальное быстродействие с минимумом издержек, лучше всего применять именно проецирование.
Совместное использование данных в этом случае происходит по следующей схеме. Несколько процессов проецируют в память представления одного и того же объекта «проекция файла», то есть делят одни и те же страницы физической памяти. Поэтому, когда один процесс записывает данные в представление общего объекта «проекция файла», эти изменения немедленно отражаются в других процессах. Но для этого все процессы должны использовать одинаковое имя объекта «проекция файла».
В предыдущем разделе рассматривалось проецирование представления файла, размещенного на диске. Но для целей обмена данными между разными процессами хранение этих данных на диске было бы очень неудобным. К счастью, Win32 API предусматривает возможность проецирования файлов непосредственно на физическую память из страничного файла, а не из специально создаваемого дискового файла.
Этот способ даже проще стандартного, рассмотренного в предыдущем разделе. Во-первых, не нужно вызывать функцию CreateFile. Вы просто вызываете функцию CreateFileMapping и передаете значение INVALID_HANDLE_VALUE (или константу -1) в параметре hFile. Но при вызове функции CreateFileMapping следует передать в последнем ее параметре С-строку, содержащую имя этого объекта. Тогда другие процессы, если им понадобится доступ к разделяемой памяти, смогут вызвать функцию OpenFileMapping и передать ей то же самое имя.
Учтите, что если разделяемая память используется в режиме записи данных более чем одним потоком, то вы должны предусмотреть синхронизацию работы этих потоков. Пример такой синхронизации при помощи объектов-событий рассматривается чуть ниже.
Когда работа с объектом «проекция файла» завершена, процесс должен вызвать функцию CloseHandle. Как только все дескрипторы объекта будут закрыты, система освободит память, переданную из страничного файла.


Июнь 01 2010

Таймеры и время

При решении некоторых задач программа должна отслеживать текущее время или выполнять какие-либо действия с определенной периодичностью. Например, эта проблема возникает в приложениях, имитирующих аппаратуру, работающую в реальном масштабе времени, в игровых и мультимедийных приложениях, а также при проведении различных тестов. Кроме того, иногда требуется отладить критичные ко времени исполнения фрагменты кода, для чего нужен «хронометр» с высокой разрешающей способностью.
Win32 API содержит как функции для измерения текущего времени, так и функции для создания виртуальных таймеров — устройств, извещающих приложение об истечении заданного интервала времени. Для успешного применения этих программных средств необходимо учитывать их разрешающую способность и потенциальную точность измерения.
Важно понимать, что многозадачная операционная система Windows не является системой реального времени, поэтому любой виртуальный таймер в Windows не может гарантировать какой бы то ни было фактической точности отсчета временного интервала. Ведь в любой момент времени система может прервать выполнение вашего приложения, чтобы дать возможность поработать другому приложению (простой, вызванный прерыванием, чаще всего длится от 1 до 30 мс1). Вероятность таких прерываний тем ниже, чем меньше рассматриваемый временной интервал и чем меньше других программ работает одновременно с вашим приложением. В то же время, как показывают эксперименты, мультимедийный таймер Windows обеспечивает вполне приемлемую фактическую точность отсчета временных интервалов для многих задач.