I have multiple threads, ThreadA and ThreadsB-Z.
ThreadA is always in critical section, popping the data out of queue and sending it on socket.
When any thread from ThreadB to ThreadZ want to enter the critical section, it wants ThreadA to leave critical section only then. It then enters the critical Section, push some data into queue and leaves critical section.
I have two problems here:
- How would ThreadB-Z (whoever wants to enter the Critical Section)
tell ThreadA to leave critical section when it wants
to access the critical section.
- I tried with the idea of SetEvent or PostThreadMessage to tell
threadA to leave the critical Section, but I am unable to handle
any Event or Thread Message since ThreadA is continuously popping
data out of the queue using while(1) and there is no message loop or
WaitforSingleObject() type thing to handle Events or Thread Messages
:(
I am like stuck in this situation. Any help/suggestion is welcome. Thanks in advance.
The real problem here is "ThreadA is always in critical section". ThreadA should not be locking the critical section indefinitely.
In C#, your code for ThreadA would look something like:
Message message;
// Only lock critical section for the time it takes to modify the queue
lock(_messageQueueLock){
message = _messageQueue.Dequeue();
}
// do something with the message
In my opinion, the following general rules of thumb should be observed when using critical sections:
- Enter and exit the critical section as quickly as possible (i.e. minimize the amount of code in the critical section).
- Use critical sections to protect a resource/asset (e.g. shared memory, queue, list, etc.)
- Avoid using critical sections to protect function/method calls. If you are making function/method calls from within a critical section... you are increasing the probability of creating deadlocks.
- Avoid trying to lock a critical section from within a critical section. Failing to do so may result in potential deadlocks within your application.
- Avoid trying to access an external resource (e.g. executing a database SQL query) while in a critical section.
- Where it makes sense, I generally like to use the following naming convention for critical sections: if the asset that is being protected is called
messageQueue
... then I would name the critical section messageQueueLock
Great quote from Microsoft: "When you use multithreading of any sort, you potentially expose yourself to very serious and complex bugs" [SOURCE: MSDN]