Повышение межпроцессного Mutex Scoped_lock - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь использовать Boost :: Interprocess для создания двух процессов, которые могут взаимодействовать друг с другом. Я прочитал многие доступные учебники и библиотеки по Boost в Интернете и не смог найти причину, по которой мой код ведет себя не так, как мне кажется.

Первый файл: (memObject.h)

#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <cstdlib>
#include <iostream>

#define bip boost::interprocess

struct userCommands
{
    userCommands()
    {}

    // User can send up to a 100-character command
    char userCommand[100];
    int userInt;

    bip::interprocess_mutex mutex;

};

Этот файл должен содержать структуру общей памяти, в которую будут записываться оба процесса.

Второй файл: (oneMutex. cpp)

// PRODUCER

#include "memObject.h"


int main(int argc, char** argv)
{

    // Establish destruction of shared memory region on program creation and destruction
    struct shm_remove
    {
        shm_remove() { bip::shared_memory_object::remove("testSharedMemory"); }
        ~shm_remove() { bip::shared_memory_object::remove("testSharedMemory"); }
    } remover;

    // Create a shared-memory object called "shm"
    bip::shared_memory_object shm(bip::create_only, "testSharedMemory", bip::read_write);

    // Set size
    shm.truncate(sizeof(userCommands));

    // Map the whole shared memory in this process
    bip::mapped_region region(shm, bip::read_write);

    // Get the address of the mapped region
    void * addr = region.get_address();
    // Construct the shared structure in memory
    userCommands * data = new (addr) userCommands;

    std::string userString;

    for (int i = 0; i < 1000; i++)
    {   // Lock the shared memory region for this scope
        bip::scoped_lock<bip::interprocess_mutex> lock(data->mutex);

        std::getline(std::cin, userString);
        strcpy(data->userCommand, userString.c_str());
        std::cout << "Should have coped: " << userString << " to the critical memory region" << std::endl;
    }

}

This file должен создать объект struct в пространстве общей памяти и запустить 'for' l oop, с помощью которого он получает доступ к общей памяти и записывает предоставленную пользователем строку в массив символов 'userCommand'.

Third Файл: (twoMutex. cpp)

// CONSUMER

#include "memObject.h"

int main(int argc, char** argv)
{   
    // Create a shared-memory object called "shm"
    bip::shared_memory_object shm(bip::open_only, "testSharedMemory", bip::read_write);

    // Set size
    shm.truncate(sizeof(userCommands));

    // Map the whole shared memory in this process
    bip::mapped_region region(shm, bip::read_write);

    // Get the address of the mapped region
    void * addr = region.get_address();
    // Construct the shared structure in memory
    userCommands * data = static_cast<userCommands*>(addr);
    //userCommands * data = new (addr) userCommands;

    std::string userString;
    int someInt;

    for (int i = 0; i < 1000; i++)
    {
        bip::scoped_lock<bip::interprocess_mutex> lock(data->mutex);

        userString = data->userCommand;
        std::cout << "Got: " << data->userCommand << " from the critical memroy region" << std::endl;
    }

}

Этот файл должен отображать пространство общей памяти в свой объект («данные») и читать из него при каждой возможности.

Вот Мой вопрос:

«Область действия» al oop в каждом отдельном примере boost :: interprocess scoped_lock была определена как «одна итерация l oop». Кажется, это согласуется с тем, что я знаю о C ++.

Однако, когда я собираю их в отдельные программы и запускаю их одновременно, процесс «Потребитель» (подробно описано в «twoMutex. cpp») не сможет получить доступ. критическая область памяти до тех пор, пока процесс 'Producer' (подробно описанный в 'oneMutex. cpp') не завершит выполнение всего файла.

Когда я переключаю код на простую схему блокировки / разблокировки путем реализации :

data->mutex.lock();
// Do stuff here
data->mutex.unlock();

Он также не работает. Только когда я ввожу некоторый сон после цикла блокировки в l oop, он вообще работает:

data->mutex.lock();
//Do stuff
data->mutex.unlock();
usleep(1e3);

Как мьютекс, второй процесс не должен ожидать доступа к критической области памяти, как только Первый закончен? Почему первый процесс может войти в критическую область памяти несколько раз, в то же время блокируя второй? Если это так, то функциональность scoped_lock фактически бесполезна.

Я сделал пример с глобальными мьютексами в одной программе на C ++, и функциональность всегда согласована: второй поток будет ожидать, пока первый поток не выполнит Fini sh, затем получить доступ к замку.

Больше всего меня смущает то, что эту библиотеку Boost , кажется, рассматривают как окончательную многоплатформенную библиотеку межпроцессных операций, но функциональность, которую она демонстрирует для своих мьютексов, в основном идет вразрез со всем, что я учили о межпроцессном взаимодействии в целом. Кроме того, при копировании примеров почти дословно из каждого источника мне удалось найти, что касается Boost :: Interprocess , они не работали так, как рекламировалось.

...