Ожидание объекта в памяти

Рейтинг: 1Ответов: 1Опубликовано: 04.05.2015

Пытаюсь дождаться объекта из разделяемой памяти. Вообще, это возможно? Есть две программы: одна посылает данные в память, другая читает:

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>

using namespace std;

#define BUF_SIZE 256
TCHAR szName[] = TEXT("Global\\MyFileMappingObject");
TCHAR nameForMutex[] = TEXT("Local\\some_name");

TCHAR szMsg[16];
int sz = 3;

int _tmain()
{
    HANDLE hMapFile;
    HANDLE hMutex;
    LPCTSTR pBuf;

    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

    hMutex = CreateMutex(NULL, true, nameForMutex);

    if (hMapFile == NULL)
    {
        _tprintf(TEXT("Could not create file mapping object (%d).\n"),
            GetLastError());
        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);

        return 1;
    }

    _stprintf_s(szMsg, _T("%d"), sz);

    CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
    int ch = _getch();
    ReleaseMutex(hMutex);

    /*int help = _ttoi(pBuf);

    cout << help << endl;*/

    UnmapViewOfFile(pBuf);

    CloseHandle(hMapFile);

    return 0;
}

Клиент:

    #include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>

using namespace std;
#pragma comment(lib, "user32.lib")

#define BUF_SIZE 256
TCHAR szName[] = TEXT("Global\\MyFileMappingObject");
TCHAR nameForMutex[] = TEXT("Local\\some_name");

int _tmain()
{
    HANDLE hMapFile;
    HANDLE hMutex;
    LPCTSTR pBuf;

    hMutex = CreateMutex(NULL, false, nameForMutex);
    WaitForSingleObject(hMutex, INFINITE);

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

    if (hMapFile == NULL)
    {
        _tprintf(TEXT("Could not open file mapping object (%d).\n"),
            GetLastError());
        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);

        return 1;
    }

    int help = _ttoi(pBuf);

    cout << help << endl;

    /*TCHAR szMsg[16];
    int sz = 5;

    _stprintf_s(szMsg, _T("%d"), sz);

    CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
    _getch();*/

    ReleaseMutex(hMutex);

    UnmapViewOfFile(pBuf);

    CloseHandle(hMapFile);

    return 0;
}

При выполнении данного кода, если запустить клиент, но не ввести значение на сервере, чтобы скопировать его в память, клиент не видит, естественно, ничего в памяти и завершается. Хотелось бы, чтобы клиент не завершался, а ждал, пока сервер не отправит в память данные, а клиент сразу же считает их из памяти и выведет. Пытался сделать с помощью WaitForSingleObject(hMapFile, INFINITE);, но программа пропускает эту строчку и идет дальше. Возможно ли вообще как-нибудь дождаться?

Ответы

▲ 3Принят

WaitForSingleObject пробует захватить объект синхронизации. Если ему удается, поток продолжает выполняться, если нет, то поток ожидает момента, когда функция сможет захватить объект. Разделяемая память не является объектом синхронизации, поэтому использовать ее так, как у вас в программе, нельзя. В вашем случае можно использовать Event или Mutex, еще есть вариант с отправкой сообщения клиенту о том, что информация записана в память и ее можно считать.

Пример с мьютексом: Сервер:

HANDLE hMutex;    

int main() {
    //что-то там ваше
    hMutex = CreateMutex(NULL, true, "Local\\some_name");
    //некоторый код, который записывает в память данные
    ReleaseMutex(hMutex);
    //что-то еще
    return 0;
}

Клиент:

HANDLE hMutex;    

int main() {
    //что-то там ваше
    hMutex = CreateMutex(NULL, false, "Local\\some_name");
    WaitForSingleObject(hMutex, INFINITE);
    //некоторый код, который читает данные из памяти
    ReleaseMutex(hMutex);
    //что-то еще
    return 0;
}