Общая отображенная память между двумя процессами не обновляется при редактировании
Я на Windows с использованием C++ и делаю простой метод для связи между двумя процессами
первый процесс создает сопоставленную память, записывает в нее первое сообщение и дублирует дескриптор для другого процесса (сопоставленная память не называется), код выглядит так:
hMapped = CreateFileMappingA(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 1000, "my_shared_memory");
if (!hMapped)
{
cout << "[!] failed to create the shared mapped memory with error : " << GetLastError() << endl;
getchar();
}
char *shared_buffer = (char*)MapViewOfFile(hMapped, FILE_MAP_ALL_ACCESS, 0, 0, mapped_memory_size);
затем другой процесс получает дескриптор, открывает представление и получает первый записанный буфер
затем он зацикливается и проверяет каждые 6 секунд новые операции записи и обрабатывает их
Я пишу с первого процесса, как это:
std::lock_guard<std::mutex> lock(mtx);
RtlSecureZeroMemory(shared_buffer, mapped_memory_size);
shared_buffer[0] = 'n'; // it's a hint for the other process
memcpy(shared_buffer + 1, this->stuff.get_data().c_str(), this->stuff.get_data().size() + 1);
но буфер не обновляется для второго процесса, это первый буфер
это код во втором процессе:
HANDLE shared_memory = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "my_shared_memory");
char *shared_buffer = (char*)MapViewOfFile(shared_memory, FILE_MAP_ALL_ACCESS, 0, 0, 1000);
utils::command_line_parser cmd_parser;
cmd_parser.parse(std::string((char*)shared_buffer + 1));
if (!cmd_parser.valid()) { // I get that they are valid and I verify that
printf("failed to parse the arguments !");
return TRUE;
}
while(true)
{
Sleep(6000);
// CloseHandle(shared_memory);
// shared_memory = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "my_shared_memory");
// shared_buffer = (char*)MapViewOfFile(shared_memory, FILE_MAP_ALL_ACCESS, 0, 0, 1000);
MessageBoxA(0, (char*)shared_buffer, "message", 0);
char res = shared_buffer[0];
switch (res)
{
case 'q' :
// do some stuff
case 'n' :
// do some stuff
break;
default:
break;
}
1 ответ
Вот пример именованного приложения с общей памятью, которое, кажется, работает с Visual Studio 2015. Приложение может быть запущено как записывающее устройство в область памяти или считывающее устройство из области памяти в зависимости от указанного аргумента командной строки.
Глядя на документацию Microsoft, похоже, что разделение дескриптора требует разветвления процесса. Функция CreateFileMappingA и из вашей первоначальной публикации и вопроса, который, кажется, не является тем, что вы делаете.
Несколько процессов могут совместно использовать представление одного и того же файла, используя один общий объект сопоставления файлов или создавая отдельные объекты сопоставления файлов, поддерживаемые одним и тем же файлом. Один объект сопоставления файлов может совместно использоваться несколькими процессами посредством наследования дескриптора при создании процесса, дублирования дескриптора или открытия объекта сопоставления файлов по имени. Для получения дополнительной информации см. Функции CreateProcess, DuplicateHandle и OpenFileMapping.
В следующем примере, используя именованную область общей памяти, я начал с исходного кода примера в CreateFileMapping, MapViewOfFile, обрабатывал утечку C++, но, будучи ленивым, я просто создал один исходный файл, консольное приложение Windows, которое я мог запустить как два разные процессы с разным поведением.
Файл исходного кода, который используется для выполнения двумя различными способами:
#include "stdafx.h"
#include <conio.h>
#include <iostream>
#define BUF_SIZE 256
TCHAR szName[] = TEXT("MyFileMappingObject");
int main(int argc, char **argv)
{
HANDLE hMapFile;
LPCTSTR pBuf;
int iInstance = 0;
TCHAR szMsgFmt[] = TEXT("Message from first process %d.");
if (argc > 1) {
iInstance = atoi(argv[1]);
}
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
BUF_SIZE, // maximum object size (low-order DWORD)
szName); // name of mapping object
DWORD lastError = GetLastError();
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
std::cin.get();
return 1;
}
pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
CloseHandle(hMapFile);
std::cin.get();
return 1;
}
for (int i = 1; i < 4; i++) {
if (iInstance > 0) {
MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);
}
else {
TCHAR szMsg[128] = { 0 };
wsprintf (szMsg, szMsgFmt, i);
std::cout << "Copying text into shared memory " << i << std::endl;
CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
std::cout << "Waiting " << std::endl;
_getch();
}
}
CloseHandle(hMapFile);
UnmapViewOfFile(pBuf);
return 0;
}
Пакетный файл 1 и пакетный файл 2 для запуска того же исполняемого файла, что и два разных процесса.
shared_mem
pause
а также
shared_mem 1
pause
и модифицированный файл включения stdafx.h.
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <Windows.h>
#include <WinUser.h>
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
Скомпилируйте исходный файл приложения, а затем запустите первый bat-файл, который запустится и поместит некоторый текст в область общей памяти, а затем подождите. Затем запустите второй файл bat, который будет читать текст из области общей памяти.
Я видел, что если вы нажмете кнопку Ok в отображаемом диалоговом окне из второго файла bat, вы снова увидите то же сообщение.
Однако если вы затем перейдете к окну первого файла bat и нажмете клавишу ввода, чтобы сгенерировать следующее сообщение, а затем вернетесь к диалогу, созданному вторым файлом bat, вы увидите, что он прочитает обновленную строку.
Это все с использованием именованного общего файла. Не пытался с дескриптором общей памяти.