![]() |
Home |
The QtSharedMemory class provides a shared memory segment. More...
#include <QtSharedMemory>
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.
Constant | Value | Description |
---|---|---|
QtSharedMemory::NoWait | 0 | The segment is destroyed immediately. |
QtSharedMemory::ForceNoWait | 1 | The segment is destroyed immediately, without attempting to acquire the shared memory lock. |
QtSharedMemory::Wait | 2 | The segment is destroyed once the number of attachments reaches 0. |
Constant | Value | Description |
---|---|---|
QtSharedMemory::InvalidSize | 0 | Failed to allocate a segment of the requested size. Try creating a smaller one. |
QtSharedMemory::KeyError | 1 | An error with the key prevented the operation from succeeding. |
QtSharedMemory::AlreadyExists | 2 | An attempt was made to allocate a shared memory segment that already exists. |
QtSharedMemory::OutOfMemory | 3 | The operation could not be completed because the system ran out of memory. |
QtSharedMemory::OutOfResources | 4 | The 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::NotFound | 5 | An attempt was made to attach to a segment that does not exist. |
QtSharedMemory::PermissionDenied | 6 | Insufficient access rights prevented an attach to a shared memory segment. |
QtSharedMemory::LockError | 7 | Unable to lock the segment, because it does not exist or has not been properly initialized. |
QtSharedMemory::UnknownError | 8 | An unrecognized error occurred. Getting this error is usually a sign that there is a bug in QtSharedMemory. |
Describes the access rights provided when allocating memory or attaching to a shared memory segment.
Constant | Value | Description |
---|---|---|
QtSharedMemory::ReadOnly | 0 | The segment can only be read from. |
QtSharedMemory::ReadWrite | 1 | The segment can both be read from and written to. |
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().
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().
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().
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().
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().
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().
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); }
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.
Returns the error type of the last failed operation.
See also errorString().
Returns a description of the cause of the last failed operation.
See also error().
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().
Returns the handle for the shared memory segment, useful for low level access. Using this function is not portable.
Returns true if the shared memory segment is valid (not empty and is attached to); otherwise returns false.
Returns this shared memory segment's key.
See also setKey().
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; }
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.
Sets the unique identifier for this shared memory segment to the string key.
See also key().
Returns the size of the shared memory segment.
Unlocks the shared memory segment.
See also lock().
Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies) | Trademarks | Qt Solutions |