简体   繁体   中英

What does it mean to have “Process persistence” for boost interprocess_mutex?

From Boost Interprocess documentation , the (anonymous) process-shared mutex types have Process persistence , which it defines as follows:

Process-persistence: The mechanism lasts until all the processes that have opened the mechanism close it, exit or crash.

Since these mutexes are anonymous, to be shared they have to be placed in some shared memory (that has longer persistence, either Kernel or Filesystem depending on the platform).

Let's consider this minimal example:

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");
}

Here are some results of running this on macOS:

  • If running processA until normal completion then processB , both processes have to create the memory, and successfully acquire the lock. This is as expected.

  • If running processA and "force quitting" it, it never reaches the clean-up code releasing the lock and removing the memory. Now, running processB the memory would already exist ( isMemoryCreated being true), which is expected because shared memory has at least Kernel persistence. But processB would not be able to lock the mutex , which seems contradictory to the boost documentation: the mutex should have process persistence, thus when processA exited it should not have persisted further.

Is that a bug in the library? Or does "Process persistence" means something different than that?

POSIX mutex, for example (used in Linux implementation of boost::interprocess), doesn't own its memory, so its persistence is that of the memory it resides in.

The code creates an anonymous mutex in a named file in the filesystem. The mutex's persistence becomes that of the named file it resides in.

When the file is unlinked, the mutex's persistence becomes process persistence.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM