Link to home
Start Free TrialLog in
Avatar of olegsp
olegsp

asked on

Thread-safe class instances

How do I make class methods thread-safe for each particular class instance, without threads for one instance interfering with the threads for the other instances?

Example:

// I have a few instances of MyClass
MyClass A, B, C;

// And I have a thread function, using MyClass instance
ThreadFunction(MyClass * pMyClass)
{
….
   pMyClass->Func1();
….
   pMyClass->Func2();
….
}

Then I am launching a lot of ThreadFunction threads, passing to each a pointer to the MyClass instance (pointer to A, B or C). Each instance (like A) may be passed to several threads; the total number of instances is not limited. I need all threads using instance A be thread-safe with respect to each other; same for all threads using instance B, etc. However, all A-threads should not block any of B-threads, etc. For example, A, B, C,… may be different files, and ThreadFunction(…) may be a file-writing function. In this case, all threads writing to the same file should be safe, but they should not interfere with the threads writing to the other files.

My app runs under Windows. If possible, I would like to avoid creating a critical section for each class instance. I also need the most time-efficient solution. I am new to thread-safe programming, so please be specific.

Avatar of MatrixDud
MatrixDud

You have to lock/unlock areas in which the threads might conflict. A simple example would be writing to a certain file (if one thread has it open the other would fail). To make it thread safe you would need to either use a CCriticalSection object or something better like CSingleLock or CMutex. You would then lock the section where problems would happen and unlock when done. You just have to be carefull where you put the lock so that threads aren't waiting around needlessly. There's not much other way to do it.
Actually, critical section for each class instance is exactly what you need. Any class function which should be thread-safe locks this critical section on the start and releases it before exit.
Avatar of olegsp

ASKER

So, if I make a critical section a member of my class, locking it will lock only its own class instance? And locking instance A will not lock instance B?

It's not like I cannot use critical sections in my class, it is more a design goal. I would really like to have the locking implemented outside the MyClass, if possible.
ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Addintinal information:
suppose you call pA->SampleFunction() from class B functions in different threads. Class A is thread-safety, this means, these two calls will not intercept each other, the will be executed one after other.
Obviously, you shouldn't call functions MessageBox when critical section is locked.
Avatar of olegsp

ASKER

OK, I agree. Is it possible then to disable thread-locking in some instances, and have it enabled in the others? 80% of my CSample objects are processed only on the main thread, and locking/unlocking them is not necessary (plus, it would introduce some performance overhead, I suppose?). I would like to have something like

pA->MakeThreadSafe(),

so that calling it will set my object in the instance-thread-safe state.
Processing 80% of objects on a single thread was the reason why I did not want to do any thread locking inside the object. However, if it needs to be done, I need to have at least some way to ignore critical sections for the objects which remain on a single thread.