Jürgen Simon
Jürgen Simon

Reputation: 896

Multiple copies of the same object (C++) : thread safe?

I have a fairly simple question, however the answer seems to elude me. If I have multiple objects of the same c++ class, each object in it's own thread, do I need to be aware of concurrent access issues? Or are things automatically thread-safe for separate instances? Of course I would expect issues with static methods, but instance methods?

Upvotes: 3

Views: 2660

Answers (6)

Matthieu M.
Matthieu M.

Reputation: 299730

You can, roughly, classify the items of C++ in 4 categories:

  • read-only: literals, constants, functions, etc... cannot be modified during the execution of code, so are inherently safe to share
  • global variables: globals at namespace scope, static attributes of a class, local static in functions, etc... can be modified, so a proper multi-thread aware mechanism must be used
  • thread-local variables: all of the above, but marked with the thread_local storage qualifier; see next point
  • instance variables: class or struct attributes, functions local variables, ... are inherently safe to use as long as they have not been explicitly shared

To sum up, you don't have to worry about the methods or functions, and can as well freely share constants.

At the middle range, make sure not to share (even inadvertently) local variables, at least not without ensuring proper synchronization on access.

And finally, be extremely wary of globals.

Upvotes: 0

thb
thb

Reputation: 14434

At the root of your question lies a question about how objects are laid out in memory. Assuming that static data members (which are rare) are not involved, each object is independent of others of the same type because the object as such, as laid out in memory, consists solely of the object's several data members. For example, suppose the type definition

class Location {
  private:
    double latitude1;
    double longitude1;
  public:
    double latitude () const { return latitude1;  }
    double longitude() const { return longitude1; }
    Location(const double lat0, const double long0) {
      latitude1  = lat0;
      longitude1 = lon0;
    }
    // Calculate the Location at exactly the furthest
    // point on earth (implemented elsewhere).
    Location antipode();
};

Suppose that separate objects of the type are elsewhere instantiated as

Location my_loc(-100.0, 35.0);
const Location your_loc(15.0, 45.5);

Then, my_loc itself consists of nothing but a pair of doubles in memory (in this case, a pair of consecutive doubles on the stack); and your_loc itself consists of nothing but a separate pair of doubles. So, you see, as far as the data goes, a Location is nothing more than a struct of two doubles.

But, you ask: what about the constuctor, and antipode(), and so forth? The answer is that they each exist only once for the class -- and, as far as memory goes, are not directly associated with the data. It is the compiler alone that associates the data with the functions. Threads don't care about that.

If you think this through in light of the foregoing, then one suspects that the answer that has eluded you will settle upon you.

Upvotes: 0

Andy Thomas
Andy Thomas

Reputation: 86381

It depends. Frequently one instance of a class will be independent of operations on other instances. If this is the case in a single thread, it is also true with multiple threads.

For example, consider a value-type class representing a Point.

class Point { 
public:
   int x, y, z 
};

An instance of this class in one thread will be unaffected by operations on a different instance in another thread.

However, an instance of a class can interact with other objects. If two instances can interact with the same object, then yes, you do need to be concerned about thread-safety.

Upvotes: 2

mathematician1975
mathematician1975

Reputation: 21351

If you have separate objects in each thread then you will be fine. You will have issues potentially if you have a static member variable in that class though.

Obviously this only applies to the data of the class objects in question if your thread functions are accessing global or shared data then the usual multithreading problems will apply.

Upvotes: 2

anio
anio

Reputation: 9161

As long as a thread from one object does not call methods on a different object, then there should be no problem.

But you might run into a deadlock still if you have recursive methods and are acquiring the mutex in the method. You will need to use recursive mutexes if that is the case.

Upvotes: 0

David V
David V

Reputation: 11699

The instance variables are all independent. So you don't need to worry about thread safety if your instance methods only use instance and local variables.

Upvotes: 1

Related Questions