Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Критическая секция в разделяемой памяти.


Автор: spz 29.10.2012, 13:24
Здравствуйте!
Необходимо синхронизировать потоки разных процессов с помощью критической секции. Для этого ее необходимо разместить в разделяемой памяти, что я и сделал:
Код

// первый процесс
if(GetLastError() != ERROR_ALREADY_EXISTS)
    {
        hSharedMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(CRITICAL_SECTION), SHARED_MEMORY_NAME);
        if(hSharedMemory != NULL)
        {
            if( (cs_ptr = (CRITICAL_SECTION*)MapViewOfFile(hSharedMemory, 
                FILE_MAP_ALL_ACCESS, 0, 0, sizeof(CRITICAL_SECTION))) != NULL)
            {
                InitializeCriticalSectionAndSpinCount(cs_ptr, 3000);
            }
            else
            {
                cout << "Error to MapViewOfFile" << endl;
                return -1;
            }
        }
    }
// второй процесс
    else
    {
        hSharedMemory = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARED_MEMORY_NAME);
        if(NULL == hSharedMemory)
        {
            cout << "Error to OpenFileMapping" << endl;
            system("pause");
            return -1;
        }

        cs_ptr = (CRITICAL_SECTION*)MapViewOfFile(hSharedMemory, 
                FILE_MAP_ALL_ACCESS, 0, 0, sizeof(CRITICAL_SECTION)); 
        if(NULL == cs_ptr)
        {
            cout << "Error to MapViewOfFile" << endl;
            system("pause");
            return -1;
        }
    }


в потоках:

             
Код

 EnterCriticalSection((CRITICAL_SECTION*)ptr);
        cout << "Thread " << "with tid " << GetCurrentThreadId() << endl; 
        Sleep(500);
    LeaveCriticalSection((CRITICAL_SECTION*)ptr);


При запуске одного экземпляра приложения(одного процесса) все нормально. Как только запускаю второй процесс, он вылетает с ошибкой на LeaveCriticalSection. Может у кого-нибудь есть какие-то предложения как это исправить?

Автор: GremlinProg 29.10.2012, 13:51
Цитата(spz @  29.10.2012,  15:24 Найти цитируемый пост)
Может у кого-нибудь есть какие-то предложения как это исправить?

через FileMapping критическую секцию разделить между процессами невозможно

Добавлено через 4 минуты и 8 секунд
можно попробовать это сделать через shared section,
но в общем случае, критические секции - инструмент синхронизации в рамках процесса.

между процессами можно пользоваться мьютексами и др. "ядерными" объектами синхронизации

Автор: feodorv 29.10.2012, 14:13
Цитата(GremlinProg @  29.10.2012,  14:51 Найти цитируемый пост)
но в общем случае, критические секции - инструмент синхронизации в рамках процесса.

Однозначно. 
Хуже того, попытка реализации "межпроцессной" критической секции приведёт к краху одного из процессов, так как при блокировке создаётся объект "событие", действительный в рамках создавшего его процесса. В другом процессе этот объект никак не регистрируется в таблице дескрипторов, и по адресу памяти, связанному с дескриптором объекта "событие" в первом, создавшем этот объект, процессе, во втором процессе может находится всё, что угодно, в том числе и недоступная для чтения-записи память. 
Пользуйтесь именованными объектами синхронизации.

Автор: Dem_max 29.10.2012, 17:11
Цитата

Пользуйтесь именованными объектами синхронизации.

типа мьютекс

Автор: bems 29.10.2012, 20:18
Цитата(feodorv @  29.10.2012,  14:13 Найти цитируемый пост)
так как при блокировке создаётся объект "событие", действительный в рамках создавшего его процесса
а еще у критической секции есть структура-спутник RTL_CRITICAL_SECTION_DEBUG, память для которой выделяется системой, поэтому она остаётся нерасшаренной

Автор: spz 29.10.2012, 22:06
Спасибо всем за ответы. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)