Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding TCriticalSection and Synchronize

I would like to confirm here if I understood correctly how TCriticalSection and Synchronize operate.

As far as I know right now Synchronize uses SendMessage (update: or at least used it in older VCL versions as mentioned in couple of comments below) which suspends currently executing thread (as well as any other thread) unlike PostMessage which doesn't and then executes required function (from main thread). In a way SendMessage "stops" multithreading when executing.

But I am not sure about TCriticalSection. Let's say for example I create something like this:

// Global variables somewhere in my code any thread can access
boost::scoped_ptr<TCriticalSection> ProtectMyVarAndCallFnction(new TCriticalSection);
int MyVariable1;
void CallMyFunctionThatAlsoModifiesMoreStuff() { /* do even more here */ };


// Thread code within one of the threads
try {
    ProtectMyVarAndCallFnction->Acquire();
    MyVariable1++;
    CallMyFunctionThatAlsoModifiesMoreStuff();
    }
__finally {
    ProtectMyVarAndCallFnction->Release();
    }

Now, my question is - how the critical section "knows" that I am protecting MyVariable1 in this case as well as whatever the called function may modify?

If I understood it correctly - it doesn't - and it is my responsibility to correctly call Acquire() in any thread wants to change MyVariable1 or call this function (or do any of the two). In other words I think of TCriticalSection as user-defined block which defines whatever logically I assigned to it. It may be a set of variables or any particular function as long as I call Acquire() within all of the threads that might write to this block or use this function. For example "DiskOp" may be my name of TCriticalSection that writes on disk, "Internet" may be the name of TCriticalSection that calls functions that retrieve some data from the Internet. Did I get it correctly?

Also, within this context, does TCriticalSection therefore always needs to be a global kind of variable?

like image 758
Coder12345 Avatar asked Dec 03 '12 13:12

Coder12345


1 Answers

SendMessage suspends currently executing thread (as well as any other thread).

No, that is incorrect. SendMessage does not suspend anything. SendMessage merely delivers a message synchronously. The function does not return until the message has been delivered. That is, the window proc of the target window has been executed. And because the window proc is always called on the thread that owns the window, this means that the calling thread may need to be blocked to wait until the window's owning thread is ready to execute the window proc. It most definitely doesn't suspend all threads in the process.

How does the critical section know that I am protecting MyVariable1?

It doesn't. It's entirely up to you to make sure that all uses of MyVariable1 that need protection, are given protection. A critical section is a form of mutex. A mutex ensures that only one thread of execution can hold the mutex any any instant in time.

As I call Acquire() within all of the threads that might write to this block or use this function.

That's not really it either. The "within all of the threads" is a mis-think. You need to be thinking about "at all sections of code that use the variable".

Does a critical section therefore always need to be a global kind of variable?

No, a critical section can be a global variable. But it need not be.

like image 193
David Heffernan Avatar answered Oct 28 '22 03:10

David Heffernan