Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> SharedMemory synchronization 
:(
    Опции темы
sol78
Дата 5.4.2009, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 7.7.2007

Репутация: нет
Всего: 0



Мне нужно организовать что то вроде shared memory  только под Виндовс для интер-процессинг.
После поисков в Гугле, использую File Mapping.  
Но ничего не нашла о реализации синхронизации между врайтером и ридером...
Т.е. как ридер дожен узнать, что есть дата.. и т.д.

Вот тут код, как лучше довести его до ума...:
Код

#ifndef _SHARED_MEMORY_
#define _SHARED_MEMORY_


#include <windows.h>
#include <stdio.h>
#include <conio.h>

#include <string>
using std::string;


class CSharedMemoryArea
{
public:
    CSharedMemoryArea(){}

    HRESULT CreateSharedMemoryArea(LPCSTR FileName);

    HRESULT    OpenSharedMemory(LPCSTR FileName);

    HRESULT DestroySharedMemoryArea ();

    void WriteOnSharedMemory(int data, int position);

    void ReadFromSharedMemory(int *data, int position);

private:
    HANDLE    m_hFile;
    LPINT    m_ipView,
        m_ipAux;  

};

#endif

Код

// ------------------------------------------------------
// Shared memory functions
// Sample file to create a Shared Memory area...
// ------------------------------------------------------

//#include <stdafx.h>

#include "SharedMemory.h"   


//________________________________________________________________
//
HRESULT CSharedMemoryArea::CreateSharedMemoryArea(LPCSTR FileName)
{

    m_hFile = CreateFileMapping(INVALID_HANDLE_VALUE, 
                                NULL,
                                PAGE_READWRITE, 
                                0, 
                                1024 * 4, 
                                FileName);
    if (m_hFile == NULL)
    {
         printf("Unable to create a file. Error %d", GetLastError());
         return 0; //@@
    }
    else 
    {
        if (GetLastError() == ERROR_ALREADY_EXISTS)
        {
            printf("A file was already created.Error %d", GetLastError());
            return 0;
        }
    }
    m_ipView = (LPINT) MapViewOfFile(m_hFile, 
                                     FILE_MAP_ALL_ACCESS,  
                                     0,
                                     0,
                                     0);
    if (m_ipView == NULL)
    {
         printf("Unable to create a VIEW.Error %d", GetLastError());
         return 0;
    }

    printf("Shared memory has been successfully created....\n");

    m_ipAux = m_ipView;
    return 1;
}    


//__________________________________________________________
//
HRESULT    CSharedMemoryArea::OpenSharedMemory(LPCSTR FileName)
{
   m_hFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, 
                           FALSE,
                           FileName);            
    if (m_hFile == NULL)
    {
         printf("Unable to open the shared area.\n");
         return 0;
    }

    m_ipView = (LPINT) MapViewOfFile(m_hFile, 
                                     FILE_MAP_ALL_ACCESS, //FILE_MAP_WRITE | FILE_MAP_READ, 
                                     0,
                                     0,
                                     0);
    if (m_ipView == NULL)
    {
         printf("Unable to create a VIEW. Error %d", GetLastError());
         return 0;
    }
    printf("Shared memory has been successfully openned....\n");

    m_ipAux = m_ipView;
    return S_OK;
}


//___________________________________________________
//
HRESULT CSharedMemoryArea::DestroySharedMemoryArea ()
{

    if (!UnmapViewOfFile(m_ipView)) 
    { 
       printf("Could not unmap view of file. Error %d ", GetLastError()); 
    } 
    
    CloseHandle(m_hFile); 
    
    printf("Shared memory has been successfully destroyed....\n");
    return 1;

}

//_________________________________________________________________
//
void CSharedMemoryArea::WriteOnSharedMemory(int data, int position)
{
    printf("Writing data on the shared area...\n");
    m_ipAux[position] = data;
}


//___________________________________________________________________
//
void CSharedMemoryArea::ReadFromSharedMemory(int *data, int position)
{
    printf("Reading data on the shared area...\n");
    *data = m_ipAux[position];
}

 
Reader
Код

// ------------------------------------------------------------
// User.cpp
//    This program uses a shared area
//      It should run AFTER the other program.
// ------------------------------------------------------------
#include <stdio.h>
#include "SharedMemory.h"

void main(int argc, char* argv[])
{
   int i, data;
   CSharedMemoryArea cSM;
   HRESULT             hr;
    
   hr = cSM.OpenSharedMemory("SharedFile");

    printf("Reading data from the shared memory area...\n");
    for (i=0; i< 100; i++) {
        cSM.ReadFromSharedMemory(&data, i);
        printf("Data[%d] = %3d\n", i, data);
    }
    printf("The reading is done.\n");
    cSM.DestroySharedMemoryArea ();
    printf("The End.");
}

Writer
Код

// ------------------------------------------------------------
// Creator.cpp
//    This program creates a shared area.
// ------------------------------------------------------------
#include <stdio.h>
#include <conio.h>
#include "SharedMemory.h"

void main(int argc, char* argv[])
{
   int i;
   CSharedMemoryArea cSM;
   HRESULT             hr;    
// creates the area to be shared
    
   hr = cSM.CreateSharedMemoryArea("SharedFile");

    printf("Writing data on the shared memory area...\n");
    for (i=0; i< 100; i++)
       cSM.WriteOnSharedMemory(i*2, i); // performs the writing

    printf("The writing is done.\n");
    printf("Now you can run the other program to read the shared area.\n");
    printf("When you want to close the shared area and finish this program...\n");
    printf("Just press a key.\n");

    
    _getch();
    cSM.DestroySharedMemoryArea (); 
    printf("The End.");
}


PM MAIL   Вверх
GoldFinch
Дата 5.4.2009, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



для синхронизации процессов есть мъютексы
или переменная в общей памяти

Это сообщение отредактировал(а) GoldFinch - 5.4.2009, 19:01
PM MAIL ICQ   Вверх
sol78
Дата 5.4.2009, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 7.7.2007

Репутация: нет
Всего: 0



можно пример реализации мутакса для данной задачи??
Что то я не пойму а кто сообщит врайтеру что есть дата?
PM MAIL   Вверх
xvr
Дата 5.4.2009, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Одного мьютекса не хватит. Кроме того непонятен протокол обмена данными через эту shared memory. Какие данные, какими порциями должны передаваться?
Тут явно понадобится мьютекс, евент или семафор и общие переменные в этой самой разделяемой памяти

PM MAIL   Вверх
sol78
Дата 5.4.2009, 23:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 7.7.2007

Репутация: нет
Всего: 0



xvr, протокол сравнительно простой. Один поток пишет данные в память и читаем другим потоком, читаем и записываем одинаковыми порциями сравнительно не большими. Важна скорость и синхронизация.  
У меня есть ридер и врайтер (2 потока). Когда у врайтера появляеся дата, он выбрасывает ивент. Ридер тем временим жидает это сыбытие. Читает данные .... а что дальше где синхронизировать дальше...??? 
PM MAIL   Вверх
asd
Дата 6.4.2009, 08:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 25.6.2006

Репутация: 1
Всего: 1



CreateNamedPipe вам поможет.
PM MAIL   Вверх
GoldFinch
Дата 6.4.2009, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



asd, так же можно слать через сокет или по POP3 на почту

Добавлено через 1 минуту и 6 секунд
Цитата(sol78 @  6.4.2009,  00:20 Найти цитируемый пост)
Когда у врайтера появляеся дата, он выбрасывает ивент. Ридер тем временим жидает это сыбытие. Читает данные .... а что дальше где синхронизировать дальше...???  

смысле что дальше? дальше ридер обрабатывает данные и ждет новых
PM MAIL ICQ   Вверх
xvr
Дата 6.4.2009, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(sol78 @ 5.4.2009,  23:20)
xvr, протокол сравнительно простой. Один поток пишет данные в память и читаем другим потоком, читаем и записываем одинаковыми порциями сравнительно не большими. Важна скорость и синхронизация.  

Т.е. вам нужна очередь пакетов фиксированной длинны. Я правильно понял?
Цитата

У меня есть ридер и врайтер (2 потока). Когда у врайтера появляеся дата, он выбрасывает ивент. Ридер тем временим жидает это сыбытие. Читает данные .... а что дальше где синхронизировать дальше...???
Дальше обрабатывает и снова ждет.
Система распадается на 2 практически независимые части - очередь (с доступом из 2х процессов) и система посылки сообщений.
Очередь организуется в виде кольцевого буфера. Все манипуляции с ней (добавление и удаление пакетов) делаются под закрытым мьютексом
Синхронизация делается в виде 2х семафоров. Один контролирует пустое пространство в очереди и его начальное значение - размер очереди в пакетах. Второй считает количество пакетов в очереди, его начальное значение - 0
Добавление пакета:
  •  Захватываем первый семафор
  •  Добавляем пакет
  •  Освобождаем второй семафор
Чтение пакета:
  •  Захватываем второй семафор
  •  Читаем пакет
  •  Освобождаем первый семафор



PM MAIL   Вверх
sol78
Дата 6.4.2009, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 7.7.2007

Репутация: нет
Всего: 0



xvr, спасибо за доступное обьяснение...
Да но я пишу под Windows, подскажите плиз  что можно использовать для реализации семафоров в Windows.
Как мутех можно использовать Критикал Секшн?
PM MAIL   Вверх
xvr
Дата 6.4.2009, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(sol78 @ 6.4.2009,  11:21)
xvr, спасибо за доступное обьяснение...
Да но я пишу под Windows, подскажите плиз  что можно использовать для реализации семафоров в Windows.

Семафоры  smile См. CreateSemaphore, OpenSemaphore
Цитата

Как мутех можно использовать Критикал Секшн?
Нет, они только в пределах процесса. См. CreateMutex, OpenMutex
PM MAIL   Вверх
Alca
Дата 6.4.2009, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Цитата

Семафоры   См. CreateSemaphore, OpenSemaphore

Код

/****************************************************************************
*    Класс: CXSemaphore (CXSemaphore.h)
*
*****************************************************************************/


#ifndef CXSemaphoreH
#define CXSemaphoreH
//---------------------------------------------------------------------------
#include <iostream>
#include <windows.h>
#include <process.h>
#include <assert.h>
//---------------------------------------------------------------------------
class CXSemaphore {
    public:
               CXSemaphore          ();
               CXSemaphore          (PSECURITY_ATTRIBUTES lpsaAttributes, LONG nInitialCount, LONG nMaxCount, LPCSTR pszName);
              ~CXSemaphore          ();
        HANDLE hGetHandle           ();
        BOOL   bCreate              (PSECURITY_ATTRIBUTES lpsaAttributes, LONG nInitialCount, LONG nMaxCount, LPCSTR pszName);
        BOOL   bOpen                (DWORD dwAccess, BOOL bInheritHandle, LPCSTR lpszName);
        BOOL   bRelease             (LONG nReleaseCount, LONG *pnOldCount);
        DWORD  dwWaitForSingleObject(DWORD dwTimeout);

    private:
        HANDLE m_hSemaphore;
};
//---------------------------------------------------------------------------
#endif

/****************************************************************************
*    Класс: CXSemaphore (CXSemaphore.cpp
*
*****************************************************************************/


#include "CXSemaphore.h"
//---------------------------------------------------------------------------
CXSemaphore::CXSemaphore() {
    m_hSemaphore = NULL;
}
//---------------------------------------------------------------------------
CXSemaphore::CXSemaphore(PSECURITY_ATTRIBUTES lpsaAttributes = NULL, LONG nInitialCount = 1, LONG nMaxCount = 1, LPCSTR lpszName = NULL) {
    m_hSemaphore = NULL;
    
    BOOL bSuccess = FALSE; 
    bSuccess = bCreate(lpsaAttributes, nInitialCount, nMaxCount, lpszName);
    if (FALSE == bSuccess) {
        return;
    }
}
//---------------------------------------------------------------------------
CXSemaphore::~CXSemaphore() {
    if (NULL != m_hSemaphore) {
        ::CloseHandle(m_hSemaphore);    m_hSemaphore = NULL;
    }
}
//---------------------------------------------------------------------------
HANDLE CXSemaphore::hGetHandle() {
    assert(NULL != m_hSemaphore);
    
    return m_hSemaphore;
}
//---------------------------------------------------------------------------
BOOL CXSemaphore::bCreate(LPSECURITY_ATTRIBUTES lpsaAttributes, LONG nInitialCount, LONG nMaxCount, LPCSTR lpszName) {
    m_hSemaphore = ::CreateSemaphore(lpsaAttributes, nInitialCount, nMaxCount, lpszName);

    return (m_hSemaphore != NULL );
}
//---------------------------------------------------------------------------
BOOL CXSemaphore::bOpen(DWORD dwAccess, BOOL bInheritHandle, LPCSTR lpszName) {
    assert(NULL != m_hSemaphore);
    
    ::OpenSemaphore(dwAccess, bInheritHandle, lpszName);
    
    return (m_hSemaphore != NULL);
}
//---------------------------------------------------------------------------
BOOL CXSemaphore::bRelease(LONG nReleaseCount = 1, LONG *pnOldCount = NULL ) {
    assert(NULL != m_hSemaphore);

    return (::ReleaseSemaphore(m_hSemaphore, nReleaseCount, pnOldCount));
}
//---------------------------------------------------------------------------
DWORD CXSemaphore::dwWaitForSingleObject(DWORD dwTimeout = INFINITE) {
    assert(NULL != m_hSemaphore);

    return (::WaitForSingleObject(m_hSemaphore, dwTimeout));
}
//---------------------------------------------------------------------------
)

Это сообщение отредактировал(а) Alca - 6.4.2009, 13:12


--------------------
PM WWW ICQ Skype Jabber   Вверх
sol78
Дата 6.4.2009, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 366
Регистрация: 7.7.2007

Репутация: нет
Всего: 0



Вот пимерно что получается:
Код

//_________________________________________________________________
//
void CSharedMemoryArea::WriteOnSharedMemory(int data, int position)
{
    DWORD dwRetCode = WaitForSingleObject(m_hPackageCounter, TIME_OUT);
    
    if (dwRetCode == WAIT_TIMEOUT)    // The defined timeout has elapsed?
    {
        printf("");

        return;
    }
    else // Add data packege to our shared memory:
    {

        // Increment the Package counter:
        if (!ReleaseSemaphore(m_hPackageCounter,
                              1,    // increase the counter by one packege
                              NULL) )  // not interested in previous count
        {
            printf("ReleaseSemaphore error: %d\n", GetLastError());
        }
        printf("Writing data on the shared area...\n");
//        m_piAux[position] = data;
    }    
    //@@@
}


//___________________________________________________________________
//
void CSharedMemoryArea::ReadFromSharedMemory(int *data, int position)
{
    DWORD dwRetCode = WaitForSingleObject(m_hFreeSpaceCouter, TIME_OUT);
    
    if (dwRetCode == WAIT_TIMEOUT)    // The defined timeout has elapsed?
    {
        printf("");

        return;
    }
    else // Add data packege to our shared memory:
    {
        //Increment the Free Space Counter:
        if (!ReleaseSemaphore(m_hFreeSpaceCouter,
                              -1,    // decrease the counter by one packege
                              NULL) )  // not interested in previous count
        {
            printf("ReleaseSemaphore error: %d\n", GetLastError());
        }
        
        printf("Reading data on the shared area...\n");
//        *data = m_piAux[position];
    }
    //@@@
}

Как реализовать 'Освобождаем первый семафор' ?

Это сообщение отредактировал(а) sol78 - 6.4.2009, 13:15
PM MAIL   Вверх
Alca
Дата 6.4.2009, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Цитата

Как реализовать 'Освобождаем первый семафор' ?

::ReleaseSemaphore


--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 6.4.2009, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



В CSharedMemoryArea::WriteOnSharedMemory WaitForSingleObject нужно делать на m_hFreeSpaceCouter, а в CSharedMemoryArea::ReadFromSharedMemory на m_hPackageCounter
И не забыть при создании установить счетчик m_hFreeSpaceCouter в максимальное количество пакетов (иначе будет deadlock)

PM MAIL   Вверх
asd
Дата 6.4.2009, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 25.6.2006

Репутация: 1
Всего: 1



Цитата(GoldFinch @  6.4.2009,  08:35 Найти цитируемый пост)
 так же можно слать через сокет или по POP3 на почту

B чем же вам пайпы не угодили? И что общего у них с сокетами и уж тем более с протоколом, который на них основан?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1679 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.