两个进程之间的命名共享内存

里卡多·阿劳霍(RicardoAraújo)

我正在尝试使用文件映射在C中构建客户端/服务器,但它仍处于开发初期,但在理解文件映射的工作原理时遇到了一些麻烦。

我在服务器上创建了一个结构的文件映射,并在上面放置了一些数据,然后我的客户端打开了文件映射,并读取了数据。然后,我的客户端将数据写入服务器以供读取,但服务器无法读取客户端数据,我也无法理解为什么,因为文件映射应该在两个进程之间进行同步。我现阶段仍未使用事件,但我认为它们不是工作所需的(是吗?)

她是我所拥有的代码。

服务器:

struct _HBACKUPSERVICE{
    DWORD           dwServerProcessID;
    TCHAR           szWork[MAX_PATH];
    HANDLE          hMapFile;
};

PHBACKUPSERVICE pBuf = NULL;
HANDLE hMapFile;

hMapFile = CreateFileMapping(
    INVALID_HANDLE_VALUE,    // use paging file
    NULL,                    // default security
    PAGE_READWRITE,          // read/write access
    0,                       // maximum object size (high-order DWORD)
    sizeof(HBACKUPSERVICE),  // maximum object size (low-order DWORD)
    _T("MyService"));        // name of mapping object

if (/*phBackupService->*/hMapFile == NULL){
    _tprintf(TEXT("Could not create file mapping object (%d).\n"),
        GetLastError());
    return *pBuf;
}

pBuf = (PHBACKUPSERVICE)MapViewOfFile(
    hMapFile,               // handle to map object
    FILE_MAP_ALL_ACCESS,    // read/write permission
    0,
    0,
    sizeof(HBACKUPSERVICE));

if (pBuf == NULL){
    _tprintf(TEXT("Could not map view of file (%d).\n"),
        GetLastError());
    return *pBuf;
}


// Populate backup service structure
pBuf->hMapFile = hMapFile;
pBuf->dwServerProcessID = GetCurrentProcessId();

// Wait for client
do{
    _tprintf(_T("\nServer: Waiting for work."));
    pBuf = (PHBACKUPSERVICE)MapViewOfFile(
        _BackupService.hMapFile,    // handle to map object
        FILE_MAP_ALL_ACCESS,        // read/write permission
        0,
        0,
        sizeof(HBACKUPSERVICE));
    if (StringCbLength(pBuf->szWork, 1 * sizeof(TCHAR), NULL) == S_OK){ Sleep(500); }
} while (StringCbLength(pBuf->szWork, 1 * sizeof(TCHAR), NULL) == S_OK); // ERROR: pBuf->szWork is always empty...

_tprintf(_T("Work from client: %s"), pBuf->szWork);

客户:

HBACKUPSERVICE _BackupService;
HANDLE hMapFile;

hMapFile = OpenFileMapping(
    FILE_MAP_ALL_ACCESS,   // read/write access
    FALSE,                 // do not inherit the name
    _T("MyService"));          // name of mapping object

if (hMapFile == NULL)
{
    _tprintf(TEXT("Could not open file mapping object (%d).\n"),
        GetLastError());
}

BackupService= (PHBACKUPSERVICE)MapViewOfFile(
    hMapFile,               // handle to map object
    FILE_MAP_ALL_ACCESS,    // read/write permission
    0,
    0,
    sizeof(HBACKUPSERVICE));

_tprintf(_T("Server process id: %d"), _BackupService.dwServerProcessID);
_tprintf(_T("send work to server"));
StringCchCopy(_BackupService.szWork, STRSAFE_MAX_CCH, _T("Do work for me!!!!!!!!!!")); //ERROR: the server never sees this

谢谢!

雷米·勒博(Remy Lebeau)

您的服务器正在MapViewOfFile()其读取循环中进行调用,因此您正在映射越来越多的指针,而不是取消映射它们。最终,您将用完所有无法映射的地址。摆脱它。在进入循环之前,应该使用pBuf从第一个指针获得指针MapViewOfFile()您只需要映射一次视图。

您的客户端根本没有将数据写入映射视图,而是在写入局部HBACKUPSERVICE变量而不是映射视图。这就是为什么服务器看不到数据的原因。

试试这个:

常见的:

typedef struct _HBACKUPSERVICE {
    DWORD           dwServerProcessID;
    TCHAR           szWork[MAX_PATH];
    HANDLE          hMapFile;
} HBACKUPSERVICE, *PHBACKUPSERVICE;

服务器:

PHBACKUPSERVICE pBuf = NULL;
HANDLE hMapFile;

hMapFile = CreateFileMapping(
    INVALID_HANDLE_VALUE,    // use paging file
    NULL,                    // default security
    PAGE_READWRITE,          // read/write access
    0,                       // maximum object size (high-order DWORD)
    sizeof(HBACKUPSERVICE),  // maximum object size (low-order DWORD)
    _T("MyService"));        // name of mapping object

if (hMapFile == NULL){
    _tprintf(TEXT("Could not create file mapping object (%d).\n"),
        GetLastError());
    return NULL;
}

pBuf = (PHBACKUPSERVICE)MapViewOfFile(
    hMapFile,               // handle to map object
    FILE_MAP_ALL_ACCESS,    // read/write permission
    0,
    0,
    sizeof(HBACKUPSERVICE));

if (pBuf == NULL){
    _tprintf(TEXT("Could not map view of file (%d).\n"),
        GetLastError());
    return NULL;
}

// Populate backup service structure
pBuf->hMapFile = hMapFile;
pBuf->dwServerProcessID = GetCurrentProcessId();
ZeroMemory(pBuf->szWork, sizeof(pBuf->szWork));

// Wait for client
_tprintf(_T("\nServer: Waiting for work."));
while (pBuf->szWork[0] == 0){ Sleep(500); }

_tprintf(_T("Work from client: %s"), pBuf->szWork);

客户:

PHBACKUPSERVICE BackupService = NULL;
HANDLE hMapFile;

hMapFile = OpenFileMapping(
    FILE_MAP_ALL_ACCESS,   // read/write access
    FALSE,                 // do not inherit the name
    _T("MyService"));          // name of mapping object

if (hMapFile == NULL)
{
    _tprintf(TEXT("Could not open file mapping object (%d).\n"),
        GetLastError());
}

BackupService = (PHBACKUPSERVICE)MapViewOfFile(
    hMapFile,               // handle to map object
    FILE_MAP_ALL_ACCESS,    // read/write permission
    0,
    0,
    sizeof(HBACKUPSERVICE));

if (BackupService == NULL){
    _tprintf(TEXT("Could not map view of file (%d).\n"),
        GetLastError());
}

_tprintf(_T("Server process id: %d"), BackupService->dwServerProcessID);
_tprintf(_T("send work to server"));
StringCchCopy(BackupService->szWork, MAX_PATH, _T("Do work for me!!!!!!!!!!"));

最后,TCHAR对于跨过程边界的互操作是危险的。想象一下,如果ANSI应用程序尝试与UNICODE应用程序通信会发生什么。他们不同意您szWork字段的格式,因此不同意您HBACKUPSERVICE结构的字节大小您应根据需要将其替换TCHARCHARWCHAR,并使其两端保持一致。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何知道两个进程之间的共享内存?

通过两个进程之间的共享内存发送 int

可以在两个单独的进程之间共享内存中的数据吗?

通过Python中的套接字在两个进程之间传递共享内存对象

Directx 12:在两个进程之间共享图形内存

使用共享内存在两个进程之间传递套接字描述符

Android在两个进程之间共享SurfaceTexture

我可以在两个进程之间共享内存而没有任何通过吗?(在Android NDK中)

进程之间共享内存

在两个进程之间共享一个串行端口

如何使用运行时大小参数构造boost spsc_queue,以使用共享内存在两个进程之间交换cv :: Mat对象?

在Linux上的进程之间共享内存

线程和进程之间共享内存

两个JVM之间的共享内存

在两个进程之间传递消息

ps aux | 两个相似进程之间的grep

在两个Python进程之间交换数据

在两个线程之间共享时间变量

如何在两个线程之间共享数据

如何在两个不同的进程之间通过python3中的指针地址共享数组?

使用什么 IPC 机制在两个 Python 进程之间共享 multiprocessing.Queue 中的数据?

类属性和进程池中的进程之间共享的内存?

两个进程无锁访问共享内存

numa 分配的内存是从两个分叉进程共享的?

linux内核如何实现2个进程之间的共享内存

在python中的两个子进程之间共享匿名mmap

使用两个管道在父进程和子进程之间进行通信

通过使用mmap()在进程之间共享内存

在单独的进程之间共享内存中的复杂python对象