Home

QtSharedMemory Class Reference

The QtSharedMemory class provides a shared memory segment. More...

    #include <QtSharedMemory>

Public Types

Public Functions


Detailed Description

The QtSharedMemory class provides a shared memory segment.

A shared memory segment is a block of memory that is accessible across processes and threads. It provides the fastest method for passing data between programs, but it is also potentially dangerous and should be used with caution. The QtSharedMemory class represents a handle to a shared memory segment.

    QtSharedMemory shared("My Shared Data");

A shared memory segment is identified with a text key. The key is set through QtSharedMemory's constructor or with setKey(), and must be unique for the segment. Two instances of QtSharedMemory using the same key will refer to the same shared memory segment.

    if (!shared.exists() && !shared.create(128)) {
        qDebug("Failed to allocate shared memory: %s",
               shared.errorString().latin1());
        return false;
    }

exists() can be used to check if the handle has any memory associated with it. Memory is allocated using create(), which optionally takes the size and permissions of the segment. The permissions apply to everyone who wishes to attach to it.

    if (!shared.attach()) {
        qDebug("Failed to attach to shared memory: %s",
               shared.errorString().latin1());
        return false;
    }

    char *byteData = (char *) shared.data();

    byteData[1] = 'a';

Before accessing the shared memory segment, it must be attached to with attach(). If this operation succeeds, data() is used to return a pointer to the shared memory segment.

When you've finished using the segment, call detach(). Call destroy() to destroy the segment, but use numAttachments() to check that there are no attachments to the segment when this is done.

Accessing a shared memory segment must always be properly synchronized with lock() and unlock():

    if (shared.lock()) {
        int *buffer = reinterpret_cast<int *>(shared.data());
        ++buffer[3];
        shared.unlock();
    }

Acquiring a lock guarantees that the shared memory segment is available and safe to read from and write to. Destroying a segment will also destroy the lock.


Member Type Documentation

enum QtSharedMemory::DestroyMode

ConstantValueDescription
QtSharedMemory::NoWait0The segment is destroyed immediately.
QtSharedMemory::ForceNoWait1The segment is destroyed immediately, without attempting to acquire the shared memory lock.
QtSharedMemory::Wait2The segment is destroyed once the number of attachments reaches 0.

enum QtSharedMemory::Error

ConstantValueDescription
QtSharedMemory::InvalidSize0Failed to allocate a segment of the requested size. Try creating a smaller one.
QtSharedMemory::KeyError1An error with the key prevented the operation from succeeding.
QtSharedMemory::AlreadyExists2An attempt was made to allocate a shared memory segment that already exists.
QtSharedMemory::OutOfMemory3The operation could not be completed because the system ran out of memory.
QtSharedMemory::OutOfResources4The operation could not be completed because the system ran out of resources. For example, some systems have a global or per-process limit on how many shared memory segments are allowed.
QtSharedMemory::NotFound5An attempt was made to attach to a segment that does not exist.
QtSharedMemory::PermissionDenied6Insufficient access rights prevented an attach to a shared memory segment.
QtSharedMemory::LockError7Unable to lock the segment, because it does not exist or has not been properly initialized.
QtSharedMemory::UnknownError8An unrecognized error occurred. Getting this error is usually a sign that there is a bug in QtSharedMemory.

enum QtSharedMemory::Mode

Describes the access rights provided when allocating memory or attaching to a shared memory segment.

ConstantValueDescription
QtSharedMemory::ReadOnly0The segment can only be read from.
QtSharedMemory::ReadWrite1The segment can both be read from and written to.


Member Function Documentation

QtSharedMemory::QtSharedMemory ( const QString & key )

Constructs a shared memory handle, where key is a string which is used to uniquely identify a segment of shared memory.

Call create() to allocate space for the segment, and call attach() to be able to read or write to the segment.

See also create() and attach().

QtSharedMemory::QtSharedMemory ()

Constructs an empty shared memory handle. The size and key are set to 0 and the empty string. setKey() must be called before create() or attach().

See also setKey().

QtSharedMemory::~QtSharedMemory ()

Destructs the QtSharedMemory, but does no implicit detach.

If you want to delete the shared memory segment, call detach(), and when numAttachments() is 0, call destroy().

bool QtSharedMemory::attach ( Mode mode = ReadWrite )

Attaches to the shared memory segment, using the permissions specified by mode. Returns true on success; otherwise returns false. If false is returned, the cause of the error can be retrieved with error() and errorString().

After attaching, data() is used to access the shared memory segment.

Note: Certain operating systems allow only a limited number of concurrent shared memory attachments per process. For example, Mac OS X seems to only allow 8 attachments. If this limit is reached, this function will return false, and error() will return QtSharedMemory::OutOfResources.

See also detach().

bool QtSharedMemory::create ( int size = 4096 )

Allocates size bytes of memory for the segment in a shared memory area. Returns true on success; otherwise returns false. If false is returned, the cause of the error can be retrieved with error() and errorString().

See also size() and destroy().

void * QtSharedMemory::data () const

If attached, returns a pointer to the shared memory segment; otherwise returns 0. The Mode the attach() was made with determines whether the data can only be read or can be both read and written to.

See also create().

bool QtSharedMemory::destroy ( DestroyMode mode = NoWait )

Destroys the shared memory segment and the lock. Returns true on success; otherwise returns false. If false is returned, the cause of the error can be retrieved with error() and errorString().

The method used when destroying the segment depends on the value of mode.

This function must be used with caution. When destroy() is called, all other accessors of the shared memory segment must have been notified to prevent access of the shared segment after it has been destroyed. Any such access will almost certainly result in a crash.

If all accessors use lock() and unlock() when accessing the shared memory, a safe way of using this function is to combine it with lock(), exists(), numAttachments() and unlock(), as in the following example:

    QtSharedMemory shared("shared.shm");
    shared.create(128);

    // Make use of the shared memory

    // Finished with the shared memory, so now we want to destroy it
    for (;;) {
        if (!shared.lock()) {
            qDebug("Unable to lock segment: %s", shared.errorString());
            break;
        }

        if (!shared.exists()) {
            qDebug("Segment has been destroyed.");
            break;
        }

        if (shared.numAttachments() == 0) {
            shared.destroy(); // also destroys the lock
            break;
        }

        shared.unlock();
        qDebug("Waiting for everybody to detach.");
        sleep(5);
    }

bool QtSharedMemory::detach ()

Detaches from the shared memory segment. Returns true on success; otherwise returns false. If false is returned, the cause of the error can be retrieved with error() and errorString().

Detaching from the segment does not destroy it; use destroy() to destroy the segment.

Error QtSharedMemory::error () const

Returns the error type of the last failed operation.

See also errorString().

QString QtSharedMemory::errorString () const

Returns a description of the cause of the last failed operation.

See also error().

bool QtSharedMemory::exists () const

Returns true if the shared memory segment exists; otherwise returns false.

Example:

    QtSharedMemory sharedMemory("Accounting app shared memory");
    if (!sharedMemory.exists() && !sharedMemory.create()) {
        qDebug("Failed to create shared memory segment: %s",
               sharedMemory.errorString().latin1());
        return;
    }

This function is only reliable when used between a lock() and an unlock(), or if the caller is certain that nobody else is accessing the shared memory segment.

See also isValid(), create(), attach(), and destroy().

int QtSharedMemory::handle () const

Returns the handle for the shared memory segment, useful for low level access. Using this function is not portable.

bool QtSharedMemory::isValid () const

Returns true if the shared memory segment is valid (not empty and is attached to); otherwise returns false.

QString QtSharedMemory::key () const

Returns this shared memory segment's key.

See also setKey().

bool QtSharedMemory::lock ()

Locks the shared memory segment. Returns true on success, indicating that the memory segment is locked and valid; otherwise returns false.

This is one of the most important functions in QtSharedMemory, and it is used to ensure safe access to the shared memory segment by avoiding race conditions.

The proper way to use this locking mechanism is to call lock() before and unlock() after every access, both when reading and writing. While locked, the segment should also be checked for validity as in the following example:

    bool increaseCounter(QtSharedMemory *shared, int counterIndex)
    {
        if (!shared->lock()) {
            qDebug("Error updating shared data: %s", shared->errorString().latin1());
            return false;
        }
        int *buffer = reinterpret_cast<int *>(shared->data());
        ++buffer[counterIndex];
        shared->unlock();
        return true;
    }

int QtSharedMemory::numAttachments () const

Returns the number of attachments to this segment. The number returned is only reliable when exactly one instance of QtSharedMemory is accessing the shared memory segment. Call this function between lock() and unlock() to get an accurate value while avoiding race conditions.

void QtSharedMemory::setKey ( const QString & key )

Sets the unique identifier for this shared memory segment to the string key.

See also key().

int QtSharedMemory::size () const

Returns the size of the shared memory segment.

void QtSharedMemory::unlock ()

Unlocks the shared memory segment.

See also lock().


Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies) Trademarks
Qt Solutions