Critical section containing another critical section? - c++

Is it permissible to nest critical section like this below?:
void somefunction()
{
EnterCriticalSection(&g_List);
...
EnterCriticalSection(&g_Variable);
...
LeaveCriticalSection(&g_Variable);
...
LeaveCriticalSection(&g_List);
}

Yes, this is acceptable. It is the norm for any slightly complicated program to have many layers of nesting in places.
The one thing you need to be aware of is that you must always take locks in the same order.
If you don't do this, you risk deadlocks in scenarios like
Thread A runs code like:
EnterCriticalSection(&g_List);
EnterCriticalSection(&g_Variable);
...
LeaveCriticalSection(&g_Variable);
LeaveCriticalSection(&g_List);
but thread B runs
EnterCriticalSection(&g_Variable);
EnterCriticalSection(&g_List);
...
LeaveCriticalSection(&g_List);
LeaveCriticalSection(&g_Variable);
This risks a deadlock where thread A locks g_List then blocks waiting on g_Variable while thread B has locked g_Variable and is blocked waiting on g_List

Related

C++ condition variables vs new threads for vectorization

I have a block of code that goes through a loop. A section of the code operates on a vector of data and I would like to vectorize this operation. The idea is to split the elaboration of the array on multiple threads that will work on subsections of the array. I have to decide between two possibilities. The first one is to create the threads each time this section is encountered an rejoin them at the end with the main thread:
for(....)
{
//serial stuff
//crate threads
for(i = 0; i < num_threads; ++i)
{
threads_vect.push_back(std::thread(f, sub_array[i]));
}
//join them
for(auto& t : threads_vect)
{
t.join();
}
//serial stuff
}
This is similar at what it is done with OpenMP, but since the problem is simple I'd like to use std::threads instead of OpenMP (unless there are good reasons against this).
The second option is to create the threads beforehand to avoid the overhead of creation and destruction, and use condition variables for synchronization (I omitted a lot of stuff for the synchronization. It is just the general idea):
std::condition_variable cv_threads;
std::condition_variable cv_main;
//create threads, the will be to sleep on cv_threads
for(....)
{
//serial stuff
//wake up threads
cv_threads.notify_all();
//sleep until the last thread finishes, that will notify.
main_thread_lock.lock();
cv_main.wait(main_lock);
//serial stuff
}
To allow for parallelism the threads will have to unlock the thread_lock as soon as they wake up at the beginning of the computation, then acquire it again at to go to sleep and synchronize between them to notify the main thread.
My question is which of this solutions is usually preferred in a context like this, and if the avoided overhead of thread creation and destruction is usually worth the added complexity (or worth at all given that the added synchronization also adds time).
Obviously this also depends on how long the computation is for each thread, but this could vary a lot since the length of the data vector could also be very short (to about two element per thread, that would led to a computation time of about 15 milliseconds).
The biggest disadvantage of creating new threads is that thread creation and shutdown is usually quite expensive. Just think of all the things an operating system has to do to get a thread off the ground, compared to what it takes to notify a condition variable.
Note that synchronization is always required, also with thread creation. The C++11 std::thread for instances introduces a synchronizes-with relationship with the creating thread upon construction. So you can safely assume that thread creation will always be significantly more expensive than condition variable signalling, regardless of your implementation.
A framework like OpenMP will typically attempt to amortize these costs in some way. For instance, an OpenMP implementation is not required to shut down the worker threads after every loop and many implementations will not do this.

Creating a 'synchronization point' between threads

I have a couple of boost::threads which all execute the same function.
void foo(){
//Lock Mutex
//Do some stuffs, part 1
//Unlock Mutex
//Do some stuffs, part 2
//Lock Mutex
//Do some stuffs, part 3
//Unlock Mutex
}
In order for my application to work, it is necessary that, before executing part 2 in parallel, all the threads have finished executing part 1.
I was not able to find any mechanism that would enable me to do that... am I missing something?
Thank you.
Use Boost barriers. Definition from official documentation:
A barrier is a simple concept. Also known as a rendezvous, it is a
synchronization point between multiple threads. The barrier is
configured for a particular number of threads (n), and as threads
reach the barrier they must wait until all n threads have arrived.
Once the n-th thread has reached the barrier, all the waiting threads
can proceed, and the barrier is reset.
extracted from here.

Get ID of executing Process/Thread in C++ Builder

Let's say I have a class with the function
class foo
{
...
void bar() {
OutputDebugString(........);
// mode code
}
}
Is it possible to print the ID of the current thread (or if it's the main application) that is executing the function using OutputDebugString?
I have a large application I'm debugging and have found a deadlock situation and would like to check which threads are included in the deadlock. Since it could possibly be the same thread that is locking it's own critical section.
Have a look at the GetCurrentThread function.
Use GetCurrentThreadId().
Note that a thread cannot deadlock itself on a critical section. Once a thread has obtained the lock to the critical section, it can freeing re-enter that same lock as much as it wants (same thing with a mutex). Just make sure to unlock the critical section for each successful lock (re)entry so that OTHER threads do not become deadlocked.

Is this function thread-safe?

I am learning multi-threading and for the sake of understanding I have wriiten a small function using multithreading...it works fine.But I just want to know if that thread is safe to use,did I followed the correct rule.
void CThreadingEx4Dlg::OnBnClickedOk()
{
//in thread1 100 elements are copied to myShiftArray(which is a CStringArray)
thread1 = AfxBeginThread((AFX_THREADPROC)MyThreadFunction1,this);
WaitForSingleObject(thread1->m_hThread,INFINITE);
//thread2 waits for thread1 to finish because thread2 is going to make use of myShiftArray(in which thread1 processes it first)
thread2 = AfxBeginThread((AFX_THREADPROC)MyThreadFunction2,this);
thread3 = AfxBeginThread((AFX_THREADPROC)MyThreadFunction3,this);
}
UINT MyThreadFunction1(LPARAM lparam)
{
CThreadingEx4Dlg* pthis = (CThreadingEx4Dlg*)lparam;
pthis->MyFunction(0,100);
return 0;
}
UINT MyThreadFunction2(LPARAM lparam)
{
CThreadingEx4Dlg* pthis = (CThreadingEx4Dlg*)lparam;
pthis->MyCommonFunction(0,20);
return 0;
}
UINT MyThreadFunction3(LPARAM lparam)
{
CThreadingEx4Dlg* pthis = (CThreadingEx4Dlg*)lparam;
WaitForSingleObject(pthis->thread3->m_hThread,INFINITE);
//here thread3 waits for thread 2 to finish so that thread can continue
pthis->MyCommonFunction(21,40);
return 0;
}
void CThreadingEx4Dlg::MyFunction(int minCount,int maxCount)
{
for(int i=minCount;i<maxCount;i++)
{
//assume myArray is a CStringArray and it has 100 elemnts added to it.
//myShiftArray is a CStringArray -public to the class
CString temp;
temp = myArray.GetAt(i);
myShiftArray.Add(temp);
}
}
void CThreadingEx4Dlg::MyCommonFunction(int min,int max)
{
for(int i = min;i < max;i++)
{
CSingleLock myLock(&myCS,TRUE);
CString temp;
temp = myShiftArray.GetAt(i);
//threadArray is CStringArray-public to the class
threadArray.Add(temp);
}
myEvent.PulseEvent();
}
Which function do you intend to be "thread-safe"?
I think that the term should be applied to your CommonFunction. This is a function that you intend to be called be several (two in this first case) threads.
I think your code has a rule on the lines of:
Thread 2 do some work
meanwhile Thread 3 wait until Thread 2 finishes then you do some work
In fact your code has
WaitForSingleObject(pthis->thread3->m_hThread,INFINITE);
maybe waits for the wrong thread?
But back to thread safety. Where is the policing of the safety? It's in the control logic of your threads. Suppose you had lots of threads, how would you extend what you've written? You have lots of logic of the kind:
if thread a has finished and thread b has finished ...
Really hard to get right and maintain. Instead you need to make CommonFunction truly thread safe, that is it needs to tolerate being called by several threads at the same time.
In this case you might do that by putting some kind of mutex around the critical part of the code, which perhaps in this case is the whole function - it's not clear whether you intend to keep the items you copy together or whether you mind if the values are interleaved.
In the latter case the only question is whether access to myArray and myShiftArray are thread safe collections
temp = myArray.GetAt(i);
myShiftArray.Add(temp);
all your other variables are local, on the stack so owned by current threads - so you just need to consult the documentation for those collections to determine if they can safely be called by separate threads.
As I've pointed out before what you are doing is entirely pointless you may as well not use threads as you fire a thread off and then wait for the thread to complete before doing anything further.
You give precious little information about your CEvent but your WaitForSingleObjects are waiting for the thread to enter a signalled state (ie for them to exit).
As MyCommonFunction is where the actual potentially thread un-safe thing occurs you have correctly critical sectioned the area, however, threads 2 and threads 3 don't run concurrently. Remove the WaitForSingleObject from MyThreadFunction3 and then you will have both running concurrently in a thread-safe manner, thanks to the critical section.
That said its still a tad pointless as both threads are going to spend most of their time waiting for the critical section to come free. In general you want to structure threads so that there is precious little they need to hit critical sections for and then, when they hit a critical section, hit it only for a very short time (ie not the vast majority of the function's processing time).
Edit:
A Critical section works by saying I'm holding this critical section anything else that wants it has to wait. This means that Thread 1 enters the critical section and begins to do what it needs to do. Thread 2 then comes along and says "I want to use the critical section". The kernel tell its "Thread 1 is using the critical section you have to wait your turn". Thread 3 comes along and gets told the same thing. Threads 2 and 3 are now in a wait state waiting for that critical section to come free. When Thread 1 finishes with the critical section both Threads 2 and 3 race to see who gets to hold the critical section first and when one obtains it the other has to continue waiting.
Now in your example above there would be so much waiting for critical sections it is possible that Thread 1 can be in the critical section and Thread 2 waiting and before Thread 2 has been given the chance to enter the critical section Thread 1 has looped back round and re-entered it. This means that Thread 1 could end up doing all its work before Thread 2 ever gets a chance to enter the critical section. Therefore keeping the amount of work done in the critical section compared to the rest of the loop/function as low as possible will aid the Threads running simultaneously. In your example one thread will ALWAYS be waiting for the other thread and hence just doing it serially may actually be faster as you have no kernel threading overheads.
ie the more you avoid CriticalSections the less time lost for threads waiting for each other. They are necessary, however, as you NEED to make sure that 2 threads don't try and operate on the same object at the same time. Certain in-built objects are "atomic" which can aid you on this but for non-atomic operations a critical section is a must.
An Event is a different sort of synchronisation object. Basically an event is an object that can be one of 2 states. Signalled or not-signalled. If you WaitForSingleObject on a "not-signalled" event then the thread will be put to sleep until it enters a signalled state.
This can be useful when you have a thread that MUST wait for another thread to complete something. In general though you want to avoid using such synchronisation objects as much as possible as it destroys the parallel-ness of your code.
Personally I use them when I have a worker thread waiting for when it needs to do something. The Thread sits in a wait state most of its time and then when some background processing is required I signal the event. The thread then jumps into life and does what it needs to do before looping back round and re-entering the wait state. You can also mark a variable as indicating that the object needs to exit. This way you can set an exit variable to true and then signal the waiting thread. The waiting thread wakes up and says "I should exit" and then exits. Be warned though that you "may" need a memory barrier that says make sure the exit variable is set before the event is woken up otherwise the compiler might re-order the operations. This could end up leaving your thread waking up finding out that the exit variable isn't set doing its thing and then going back to sleep. However the thread that originally sent the signal now assumes the thread has exited when it actually hasn't.
Whoever said multi-threading was easy eh? ;)
It looks like this is going to work because the threads aren't going to do any work concurrently. If you change the code to make the threads perform work at the same time, you will need to put mutexes (in MFC you can use CCriticalSection for that) around the code that accesses data members which are shared between the threads.

C++ context switch and mutex problem

Ok.. here is some background on the issue. I have some 'critical' code that i'm trying to protect with a mutex. It goes something like this
Mutex.Lock()
// critical code
// some file IO
Mutex.Unlock().
Now the issue is that my program seems to be 'stuck' due to this. Let me explain with an example.
Thread_1 comes in; and go to Mutex.Lock() and starts executing the critical code. In the critical code; it needs to do some File IO. Now at this point; I believe a 'context switch' happens and Thread_2 comes in and blocks on the Mutex.Lock() (since Thread_1 has the lock). All seems fine but in my case; the program 'hangs' here.. The only thing I can think of is that somehow Thread_2 keeps blocking for ever and doesn't switch back to Thread_1??
More info: using pthread_mutex_init and pthread_mutex_lock on linux.
As others have mentioned, you probably have a deadlock.
Sidenote:
You'll want to make sure that there aren't any uncaught exceptions thrown in the critical block of code. Otherwise the lock will never be released. You can use an RAII lock to overcome this issue:
class SingleLock {
public:
SingleLock(Mutex &m) : m(m) { m.Lock(); }
~SingleLock() { m.Unlock(); }
private:
Mutex m;
};
...
{
SingleLock lock(mutex);
// critical code // some file IO
}
...
This sounds like a deadlock where Thread_1 is in the mutext and waiting on Thread_2 to release something, while Thread_2 is waiting to enter the mutex and so can't release whatever it is that Thread_1 needs.
edit: swapped thread names to more closely match the scenario in the question, added 'in the mutex'
The best solution for something like this is to use the debugger (gdb?). It is better if you use any IDE with debugger (eclipse?) to make debugging easier and more visual.
Like this you will see the location at which every thread is waiting.
What I expect is that Thread1 locks the mutex to enter the critical section, the stuck in the IO (may be wrong reading or infinite loop) and thread two is normally waiting for Mutex to be unlocked.
It doesn't seem that this is a dead lock, because dead lock can't happen with a single mutex!
The context switch is irrelevant so long as there's just one lock. The other thread can't do anything to affect the first one as it will just be waiting on the lock until it gets it. So the problem is with the first thread somehow. Debuggers are pretty much worthless for multithreading but deadlocks are usually easy to resolve, as someone pointed out probably the first thread is in an infinite loop somehow.
Does the File I/O need to be part of the critical section? If Thread 1 is doing a blocking read, and Thread 2 is what is supposed to be writing to that file (or pipe or similar), then Thread 1 will never return to release the mutex. You should evaluate your critical sections to determine what actually needs to be protected by the mutex. It's considered good practice to have your critical sections be as small as possible.