CopperSpice API  1.9.1
Thread Safety

The concept of thread-safety in a method or function refers to the idea that the caller does not need to worry about locking any shared resources.

The term conditionally thread safe is a weaker form of thread-safety. A conditionally thread safe method or function can be called simultaneously in multiple threads as long as each thread is operating on its own objects. In other words, the threads are not sharing any resources.

A thread-safe method or function is always conditionally thread safe, however the reverse is not always true.

Conditionally Thread Safe Classes

A class is conditionally thread safe if different instances of the class can be used simultaneously in multiple threads. For example, the methods of the class QString are all conditionally thread safe since they only access data of the given instance.

C++ classes are often conditionally thread safe simply because they only access their own member data.

As another example the Counter class below is conditionally thread safe but not thread-safe. If multiple threads call increment() or decrement() on the same instance of counter, the result is undefined behavior.

class Counter
{
public:
Counter() { n = 0; }
void increment() ++n; }
void decrement() { --n; }
int value() const { return n; }
private:
int n;
};

Thread Safe

One way for the Counter class to be thread-safe is to serialize the operations. Thread A must perform each operation without interruption before thread B can perform any operations. One simple way to implement this is to protect all access to the data members with a QMutex.

This example is not necessarily the most efficient way to make the class thread-safe. If this counter was heavily used a more sophisticated approach would be required.

class Counter
{
public:
Counter() { n = 0; }
void increment() { QMutexLocker locker(&mutex); ++n; }
void decrement() { QMutexLocker locker(&mutex); --n; }
int value() const { QMutexLocker locker(&mutex); return n; }
private:
mutable QMutex mutex;
int n;
};

The QMutexLocker class automatically locks the mutex in its constructor and unlocks the mutex when the local goes out of scope. Locking the mutex ensures that access from different threads will be serialized.

CopperSpice Classes

Many CopperSpice classes are conditionally thread safe, however they are not thread-safe. Making a class thread-safe usually adds overhead like repeatedly locking and unlocking a QMutex.

For example QList is conditionally thread safe but not thread-safe. You can safely access different instances of QList from multiple threads simultaneously, however you can not safely access the same QList from multiple threads simultaneously.