Что значит иметь «персистентность процесса» для boost interprocess_mutex? - PullRequest
0 голосов
/ 10 апреля 2019

Из Повысить межпроцессную документацию , (анонимные) разделяемые процессом типы мьютексов имеют Постоянство процесса , которое определяется следующим образом:

Процесс-постоянство: механизм действует до тех пор, пока все процессы, открывшие механизм, не закроют его, не завершат работу или не завершат работу.

Поскольку эти мьютексы являются анонимными, для совместного использования их необходимо поместить в некоторую общую память (чтоимеет более длительное постоянство (ядро или файловая система в зависимости от платформы).

Давайте рассмотрим этот минимальный пример:

namespace bi = boost::interprocess;

{
    bool isMemoryCreated = /*assume function to get this info*/;

    bi::shared_memory_object shm = [&]() -> bi::shared_memory_object
    {
        if (isMemoryCreated)
        {
            return {bi::open_only, "sharemem", bi::read_write};
        }
        else
        {
            bi::shared_memory_object shm{bi::create_only, "sharemem", bi::read_write};
            shm.truncate(sizeof(bi::interprocess_mutex));
            return shm;
        }
    }();

    //Map the whole shared memory in this process
    region = bi::mapped_region(shm, bi::read_write);
    void * address = region.get_address();

    bi::interprocess_mutex mutex = [&]() 
    {
        if (isMemoryCreated)
        {
            return static_cast<bi::interprocess_mutex*>(address);
        }
        else
        {
            return new (address) bi::interprocess_mutex;
        }
    }();

    std::cout << mutex->try_lock() << std::endl;

    // wait on external condition

    mutex->unlock();
    bi::shared_memory_object::remove("sharemem");
}

Вот некоторые результаты выполнения этого на macOS:

  • Если запустить processA до нормального завершения, то processB , оба процесса должны создать память и успешно получить блокировку.Это как и ожидалось.

  • Если запустить processA и принудительно завершить его, он никогда не достигнет кода очистки, снимающего блокировку и удаляющего память.Теперь, при запуске processB память уже будет существовать (isMemoryCreated будет иметь значение true), что ожидается, поскольку общая память имеет по крайней мере постоянство ядра.Но processB не сможет заблокировать мьютекс , что кажется противоречащим документации буста: мьютекс должен иметь постоянство процесса, поэтому при выходе из processA он не должен был сохраняться дальше.

Это ошибка в библиотеке?Или «Постоянство процесса» означает нечто иное, чем это?

1 Ответ

0 голосов
/ 10 апреля 2019
Например,

мьютекс POSIX (используемый в Linux-реализации boost :: interprocess) не владеет своей памятью, поэтому его постоянство соответствует памяти, в которой он находится.

Код создает анонимный мьютекс в именованном файле в файловой системе. Постоянство мьютекса становится постоянным для именованного файла, в котором он находится.

Когда файл не связан, постоянство мьютекса становится постоянством процесса.

...