c# - Is there a way to wait on multiple semaphors -


I am trying to write an application that can wait on several resource pools at one go. Each resource pool is controlled by Safe . Can I use WaitHandle.WaitAll () , where I am in the full list of weekly? Is there a potential deadlock problem with this implementation?

My current implementation:

  Namesplace XXX {System.Collections.Generic; Using System.Linq; Using System.Threading; Public Class Resourceful Manager {Private Readonly ID Works & lt; String, semaphore & gt; ResourcesPolicies = New Dictionary & lt; String, semaphore & gt; (); Public Zero AddResourcePool (string resource name, int maxConcurrentConsumers) {this.resourcePools.Add (resource name, new semaphore (Maximer Consumers, MaxConverter Consurs)); } Public Zero RequestResource (string resource name) {this.resourcePools [resourceName] .WaitOne (); } Public Zero RequestMultipleResources (string [] resource names) {semaphore [] resources = resourcename Select (s = & gt; this. Resources [s]). ToArray (); WaitHandle.WaitAll (resource); } Public Zero Release Resources (string resource name) {this.resourcePools [resourceName]. Revision (1); }}}}  

Of course, you can use it, but only if On the basis of the composition of the rest of your application, there may indeed be issues of starvation, all semaphores are triggered at once. For example, if you have two resources, A and B, and three threads:

  1. Take the resource A continuously, work with it for a second, then leave it and loop < / Li>
  2. You can easily wait forever to be available for both A and B forever.

    Depending on your application, it may be better to just take each semaphore in order, which avoids this hunger but introduces issues with traditional obstacle though, if you are making sure These locks will be available most of the time, so it can be safe (but it is waiting for your time to be bomb just in real time).

    Looking at your sample code, one more option will be to create a global order on semaphore - say, a command by name - and always be sure to get them in that sequence if you do so , You can multi-lock by locking one by one in ascending order one by one.

    In this case, the sequence of release is not strictly - but if you exit the order, you should leave all the locks "after" lock which you have already done before any further acquisition. (This is the rule of thumb which you should stutter, it may be possible to relax more with detailed analysis). Recommended method is possible where the acquisition will need to be released in the reverse order, in this case you can contract it for acquisition at any time.

  3. Get Lock C
  4. Get Lock C
  5. Get Lock C
  6. Release Lock C
  7. Release B (do not get anything until you release D!)
  8. Release D
  9. Receive
  10. Release E
  11. Release A

Until all of the rules follow these rules, the deadlock should not be possible, because the waiter can not have cycles.

The downside of this approach is that delaying waiting for other threads to wait for another can be delayed; it will not be forever; In the example above three threads, we can see this scenario as an example:

  1. Initially, thread 2 holds. Thread 1 has one.
  2. (time pass)
  3. thread 1 release a.
  4. Thread 3 locks on A, B block.
  5. Thread 1 block
  6. (time pass)
  7. Thread 2 release b.
  8. Thread 3 locks, works, then unlocks.
  9. Thread 1 locks, progresses.

As you can see, there was some downtime in which thread 1 was blocked at A, even if no actual work was done. However, by doing this we have significantly improved the possibilities of Thread 3 so that everyone can make progress.

Is this a good trade off, it will depend on your application - if you can definitely say that many threads never lock, maybe this may not be the case but someone Not right :)


Comments

Popular posts from this blog

python - Overriding the save method in Django ModelForm -

html - CSS autoheight, but fit content to height of div -

qt - How to prevent QAudioInput from automatically boosting the master volume to 100%? -