2 ТРАНСФЕР НА ДАННИ МЕЖДУ ПРОЦЕСИТЕ

Започваме нашето изследване на средствата за комуникация между процесите с карти на паметта файлове. Този метод е много бърз, защото данните се прехвърлят между процесите директно през виртуална памет.

Техниката за работа с карти на паметта файлове беше описана в първата глава. Тази техника може да се използва без промени за организиране на прехвърлянето на данни между процесите, но все пак правим някои забележки.

Спомнете си, че картографирането се създава от функцията CreateFileMapping.

Ето кодов фрагмент от приложението Oem2Char, който създава картографиране на файл и след това картографира този файл в паметта:

Тук, като първи параметър към функцията CreateFileMapping, предаваме идентификатора на файла, отворен от функцията CreateFile. Последният параметър е посочен като NULL, така че картографирането няма име.

Ако картографирането ще се използва за предаване на данни между процесите, е удобно да му дадете име. Използвайки това име, други процеси могат да отворят картографирането с функцията OpenFileMapping.

Друга бележка се отнася до идентификатора на файла, предаван на функцията CreateFileMapping чрез първия параметър. Ако създавате съпоставяне само за да позволите предаването на данни между процесите, не е необходимо да създавате файл на диска на вашия компютър. Като посочите (HANDLE)0xFFFFFFFF като файлов идентификатор, вие създавате преобразуването директно във виртуалната памет, без да използвате допълнителен файл.

Ето кодов фрагмент, който създава съпоставяне с име $MyVerySpecialFileShareName$ и това съпоставяне се създава във виртуална памет:

След като сте създали обект за картографиране, трябва да картографирате файла в паметта, когатос помощта на функцията MapViewOfFile, както е показано по-горе. Ако е успешна, тази функция ще върне указател към картографираната област на паметта.

Така че първият процес е създал картографиране. Вторият процес, който ще комуникира с първия процес, трябва да отвори това картографиране по име с помощта на функцията OpenFileMapping, като това:

След това второто приложение извършва картографирането чрез извикване на функцията MapViewOfFile:

Използвайки стойността, получена от функцията MapViewOfFile, второто приложение получава указател към картографираната област на паметта. Физически тази област е в същите страници с виртуална памет като областта, създадена от първия процес. Така два процеса получиха указатели към страници със споделена памет.

Преди да завършат работата си, процесите трябва да декартират файла и да освободят идентификатора на създадения обект за картографиране:

Приложение Fmap/сървър

За да илюстрираме техниката за обмен на данни между различни процеси, използвайки карти с памет, подготвихме изходния код за две конзолни приложения: Fmap/Server и Fmap/Client. Тези приложения работят по двойки (Фигура 2.1).

Ориз. 2.1. Взаимодействие на конзолни приложения Fmap/Server и Fmap/Client

Приложението Fmap/Server създава картографиране и два обекта за събития. Първият обект е за работа с клавиатурата, вторият е за откриване на прекратено действие на приложението Fmap/Client. Обектите на събитията бяха описани от нас в предишния том на „Библиотеката на системния програмист“, посветен на програмирането за операционната система Microsoft Windows NT.

Приложението Fmap/Client отваря създаденото картографиране и обекти за събития и след това преминава през въвеждането от клавиатурата, превключвайки един от обектите за събитие към маркирания.състояние при въвеждане на всеки символ. Въведените кодове на знаци се записват в картираната памет.

Докато потребителят въвежда знаци в прозореца на приложението Fmap/клиент, приложението Fmap/сървър ги показва в прозореца си, като получава кодовете на въведените знаци от картираната памет. За синхронизация се използва обект за събитие, предназначен за работа с клавиатурата.

Ако потребителят натисне клавиш в прозореца на приложението Fmap/клиент, приложението маркира както събития, така и изходи. Приложението Fmap/Server, след откриване, че вторият обект на събитието е в проверено състояние, също излиза. По този начин, ако приложението Fmap/клиент бъде прекратено, приложението Fmap/сървър също ще бъде прекратено.

Изходният код за приложението Fmap/Server е показан в списък 2.1.

Списък 2.1. ФАЙЛ fmap/сървър/server.c

Глобалните променливи hEventChar и hEventTermination съхраняват идентификаторите на обектите за събития, предназначени съответно за работа с клавиатурата и за фиксиране на момента на прекратяване на Fmap/клиентското приложение. Същите идентификатори се записват в глобалния масив hEvents, който се използва от функцията WaitForMultipleObjects.

Глобалните имена на обекти на събития се съхраняват в променливите lpEventName и lpEventTerminationName.

Името на картографиране се съхранява в масива lpFileShareName, а идентификаторът на картографиране се съхранява в глобалната променлива hFileMapping.

Основната функция на приложението Fmap/Server създава два обекта за събития с помощта на функцията CreateEvent. Ще намерите описание на тази функция в предишния том „Библиотеки на системния програмист“.

След това основната функция създава обект за картографиране и извършва картографирането чрез извикване на CreateFileMapping иMapViewOfFile. Тъй като (HANDLE)0xFFFFFFFF се предава като файлов идентификатор към функцията CreateFileMapping, картографирането ще бъде създадено директно във виртуалната памет, без да се използва файл, намиращ се на диска.

След като масивът hEvents бъде инициализиран, основната функция стартира цикъл, който чака събития и извежда символите, записани от Fmap/Client, в картографираната област на виртуалната памет.

Функцията WaitForMultipleObjects се използва за изчакване на две събития. Третият параметър на тази функция е FALSE, така че изчакването се прекратява, ако някое от събитията влезе в проверено състояние.

Когато обектът на събитието hEventTermination влезе в проверено състояние, функцията WaitForMultipleObjects връща стойността WAIT_OBJECT_0. При откриване на това основната функция излиза, защото събитието hEventTermination се задейства, когато Fmap/клиентът излезе.

Ако обектът на събитието hEventChar премине към маркираното състояние, функцията WaitForMultipleObjects връща стойността WAIT_OBJECT_0 + 1. В този случай основната функция чете първия байт от картографираната област на паметта и го извежда в прозореца на конзолата, използвайки добре познатата функция putch от програмирането на MS-DOS:

Преди да приключи, главната функция затваря идентификаторите на обекта на събитието, анулира картографирането и освобождава идентификатора за картографиране.

Fmap/клиентско приложение

Изходният код за приложението Fmap/клиент, проектиран да работи с приложението Fmap/сървър, е показан в листинг 2.2.

Списък 2.2. Файл fmap/client/client.c

След създаване на обекти за събития, предназначени за синхронизиране на работата сПриложение Fmap/Server, основната функция на приложението Fmap/Client отваря картографирането с помощта на функцията OpenFileMapping, както е показано по-долу:

Името на картографирането тук е $MyVerySpecialFileShareName$, точно същото като в приложението Fmap/Server.

След това, ако е успешно, се извършва картографиране на паметта:

Ако картографирането е успешно, глобалната променлива lpFileMap се настройва на указател към картографираната област на паметта и след това се стартира цикъл за въвеждане на знаци.

Символите се въвеждат чрез функцията за въвеждане на конзолата getche. Резултатът се съхранява в първия байт на картографираната област на паметта, откъдето приложението Fmap/Server ще го вземе за изход:

След приключване на записа основната функция поставя обекта събитие за работа с клавиатурата в маркираното състояние.

Ако потребителят натисне клавиша в прозореца на приложението Fmap/Client, който има код 27, цикълът се прекъсва. И двата обекта на събитието се преместват в маркираното състояние, след което идентификаторите на тези обекти се освобождават.

Преди да излезе, основната функция декартира файла и освобождава идентификатора на обекта за картографиране.