Do I need to DeleteCriticalSection in Destructor? - c++

I'm new to C++ and in my program I have a class that has a private member (CRITICAL_SECTION csPtr).
The InitializeCriticalSection(&csPtr) is called in my constructor.
My question is, do I need to call DeleteCriticalSection(&csPtr) in my destructor?

Yes, according to MSDN:
A critical section object cannot be moved or copied. The process must also not modify the object, but must treat it as logically opaque. Use only the critical section functions to manage critical section objects. When you have finished using the critical section, call the DeleteCriticalSection function.

Related

C++ MultiThreading: What happens if destructor and member function are running in separate threads

I have a class object whose functions can be called from different threads.
It is possible to get into a situation where Thread1(T1) is calling destructor,
whereas Thread(T2) is executing some other function on the same object.
Let's say T1 is able to call the destructor first, then what happens to the code running in T2?
Will it produce a crash or since the object is already destroyed, the member function will stop running?
Will taking a mutex lock at entry and unlocking at exit of all class functions ensure that there is no crash in any kind of race that will happen between destructor and member functions?
Appreciate your help!
No. Because the logic is flawed. If it is possible at all that T1 is calling the destructor, a mutex will not prevent it from still trying to do that.
There is shared data between T1 and T2 and as such you must make sure that neither will try to call methods on a non-existing shared object.
A mutex alone will not help.
What you'll get is unknown and unpredictable. You're describing a classic multithreading bug / poor design.
An instance should be properly locked before use, and that includes destruction. Once you do that, it's impossible to call a member function on an instance that's being destroyed in another thread.
Locking inside the functions won't help since if 2 separate threads hold references to the same instance and 1 of them causes it to be destroyed, the other thread is holding a bad reference and doesn't know that. A typical solution is to use refcounts, where destruction is at the responsibility of the object itself once no references to it exist. In C++, you'd usually use shared_ptr<> to do this.

Destructor vs member function race again

I've already seen similar question: Destructor vs member function race
.. but didn't find the answer for the following. Suppose we have a class owning some worker thread. Destructor of the class can look like:
~OurClass
{
ask_the_thread_to_terminate;
wait_for_the_thread_to_terminate;
....
do_other_things;
}
The question is: may we call OurClass's member functions in the worker thread as we are sure all these calls will be done before do_other_things in the destructor?
Yes you can. Destruction of member variables willonly start after do_other_things completes its execution. It is safe to call member functions before object gets destructed.
Well, you kinda can do that, but it's easy to make a mistake this way. For example, if you do something like:
~OurClass
{
delete *memberPointer_;
ask_the_thread_to_terminate; // the thread calls OurClass::foo();
wait_for_the_thread_to_terminate;
....
do_other_things
}
void OurClass::foo()
{
memberPointer->doSomething();
}
you will be in trouble. It also makes it harder to read through the code. So you will have to be careful with the order of operations and stuff like that. In general if it's possible to change the architecture to avoid such complicated constructions, I would suggest to do it.
The implicit destruction of any data members occurs after execution of the last explicit line of your destructor, so all those data members are still fully functional whilst you wait for the thread. Hence, you must only avoid any premature explicit destruction of any data members (as exemplified in SingerOfTheFall's pathological code).

What happens if I call an objects member function from a different thread?

If I have an C++ object created in the main thread, and then start another thread, and from that thread I call a public member function of the object I created, what happens?
Is it different if the public function has parameters or if it manipulates private object members?
Does it behave differently on windows, linux or mac os?
What happens if the object is created on the stack?
There are two points that matter:
first, as usual, you need to esnure that the lifetime of the instance exceeds the duration of its usage.
second, access to variables across multiples threads need be synchronized to prevent race conditions.
That's all folks.
Each thread has a own stack and thus you can have concurrent streams of execution. It is your own duty to make the object thread-safe.
It does not matter. However, private members are a candidate for race conditions.
If you create an object on the stack, it won't be accessible from another thread.
If I have an C++ object created in the main thread, and then start another thread, and from that thread I call a public member function of the object I created, what happens?
It depends on lifetime of the object.
If the object is created on heap(dynamic memory using new) then the other thread will access the members of the object correctly(assuming no race conditions) unless the lifetime of the object ended by calling delete in the first thread.
If the object is created on stack(locally) in the first thread then you will have a *Undefined Behavior*if the lifetime of the created object ended before being accessed in second thread.
Why can you access the object on stack in second thread?
Each thread has its own stack and unless the object created on stack of thread is valid and alive You would be trying to access an address location which doesn't point to any valid object in second thread.
Note that each process has an address space and all threads in the same process share the same address space, hence the address of the variable can be accessed in the second thread. However, You need to ensure that address contains a valid object.
Is it different if the public function has parameters or if it manipulates private object members?
Access specifiers and multithreading are not related at all.
Same access specifier rules apply in all threads.
Does it behave differently on windows, linux or mac os?
The answer to #1 is guaranteed on all Operating systems.
Compared to the original behaviour there should be no differences if created on the heap. However there are some culprits of course, usually known under the term "thread safety". If you access the same member from different threads, you have to ensurse that accessing the same resources does not lead to a "race condition".
To avoid race conditions you can use different kind of "locks", for instance mutexes etc. When using using lock objects there is another culprit: The danger of "deadlocks", if two accessors wait for each other and the original lock never gets released.
It will work perfectly well. Objects do not belong to any specific thread and can equally well be called from anywhere.
However, and this is important, calling member function on two threads at the same time will cause problems where you update some data in one thread while reading it in another. You need to either arrange your code to ensure this can't happen, or ensure that your threads coordinate access (using mutex most likely)
What happens is exactly what happens if you call it from the same
thread. The same machine code gets executed. The only potential
difference is that you can have several threads accessing the object at
the same time; it's up to you to protect against this (at least if any
of the threads is modifying the object—otherwise, no protection is
needed).
In the case of an object on the stack, you have to consider lifetime
issues, but this is the case anyway; save a pointer to an object on the
stack in a global variable, then leave the scope where the object was
defined, and the global variable becomes a dangling pointer; trying to
access the object through it is undefined behavior (and calling a
non-static member function on it it is considered using it). Whether
the access is from the same thread or a different thread doesn't change
anything.

Is this way of creating static instance thread safe?

I have the following sample C++ code:
class Factory
{
public:
static Factory& createInstance()
{
static Factory fac;
return fac;
}
private:
Factory()
{
//Does something non-trivial
}
};
Let's assume that createInstance is called by two threads at the same time. So will the resulting object be created properly? What happens if the second thread enters the createInstance call when the first thread is in the constructor of Factory?
C++11 and above: local static creation is thread-safe.
The standard guarantees that:
The creation is synchronized.
Should the creation throws an exception, the next time the flow of execution passes the variable definition point, creation will be attempted again.
It is generally implemented with double-checking:
first a thread-local flag is checked, and if set, then the variable is accessed.
if not yet set, then a more expensive synchronized path is taken, and if the variable is created afterward, the thread-local flag is set.
C++03 and C++98: the standard knows no thread.
There are no threads as far as the Standard is concerned, and therefore there is no provision in the Standard regarding synchronization across threads.
However some compilers implement more than the standard mandates, either in the form of extensions or by giving stronger guarantees, so check out for the compilers you're interested in. If they are good quality ones, chances are that they will guarantee it.
Finally, it might not be necessary for it to be thread-safe. If you call this method before creating any thread, then you ensures that it will be correctly initialized before the real multi-threading comes into play, and you'll neatly side-step the issue.
Looking at this page, I'd say that this is not thread-safe, because the constructor could get called multiple times before the variable is finally assigned. An InterlockedCompareExchange() might be needed, where you create a local copy of the variable, then atomically assign the pointer to a static field via the interlocked function, if the static variable is null.
Of course it's thread safe! Unless you are a complete lunatic and spawn threads from constructors of static objects, you won't have any threads until after main() is called, and the createInstance method is just returning a reference to an already constructed object, there's no way this can fail. ISO C++ guarantees that the object will be constructed before the first use after main() is called: there's no assurance that will be before main is called, but is has to be before the first use, and so all systems will perform the initialisation before main() is called. Of course ISO C++ doesn't define behaviour in the presence of threads or dynamic loading, but all compilers for host level machines provide this support and will try to preserve the semantics specified for singly threaded statically linked code where possible.
The instantiation (first call) itself is threadsafe.
However, subsequent access will not be, in general. For instance, suppose after instantiation, one thread calls a mutable Factory method and another calls some accessor method in Factory, then you will be in trouble.
For example, if your factory keeps a count of the number of instances created, you will be in trouble without some kind of mutex around that variable.
However, if Factory is truly a class with no state (no member variables), then you will be okay.

How does Multiple C++ Threads execute on a class method

let's say we have a c++ class like:
class MyClass
{
void processArray( <an array of 255 integers> )
{
int i ;
for (i=0;i<255;i++)
{
// do something with values in the array
}
}
}
and one instance of the class like:
MyClass myInstance ;
and 2 threads which call the processArray method of that instance (depending on how system executes threads, probably in a completely irregular order). There is no mutex lock used in that scope so both threads can enter.
My question is what happens to the i ? Does each thread scope has it's own "i" or would each entering thread modify i in the for loop, causing i to be changing weirdly all the time.
i is allocated on the stack. Since each thread has its own separate stack, each thread gets its own copy of i.
Be careful. In the example provided the method processArray seems to be reentrant (it's not clear what happens in // do something with values in the array). If so, no race occurs while two or more threads invoke it simultaneously and therefore it's safe to call it without any locking mechanism.
To enforce this, you could mark both the instance and the method with the volatile qualifier, to let users know that no lock is required.
It has been published an interesting article of Andrei Alexandrescu about volatile qualifier and how it can be used to write correct multithreaded classes. The article is published here:
http://www.ddj.com/cpp/184403766
Since i is a local variable it is stored on the thread's own private stack. Hence, you do not need to protect i with a critical section.
As Adam said, i is a variable stored on the stack and the arguments are passed in so this is safe. When you have to be careful and apply mutexes or other synchronization mechanisms is if you were accessing shared member variables in the same instance of the class or global variables in the program (even scoped statics).