c# - Long-running access to a shared resource with the ability to release on request -
i'm not sure how best explain want, let me write illustrative code. basically: background thread loops through lots of work, on rare occasions needs interrupted.
// loop runs in long-running thread // lot of high-priority work on shared resource. // vast majority of time thread accessing resource. private void fastloop() { lock (locker) { while (true) { dowork(); // somehow checking if thread needs shared resource. // ideally i'd this, // alas: monitor.blockedcount() doesn't exist. while (monitor.blockedcount(locker) > 0) monitor.wait(locker); } } } // methods called rarely, there many of them // code required lock , unlock secondary threads // should simple. private void otherthreads() { lock (locker) { dosomethingelse(); monitor.pulse(locker); } } the current implementation uses simplest approach, unlocking , locking again give other threads opportunity jump in.
private void fastloopcurrentimplementation() { while (true) { lock (locker) dowork(); } } private void otherthreadscurrentimplementation() { lock (locker) dosomethingelse(); } something tells me simplistic approach might have issues, though. if i'm not mistaken, loop can unlock , lock again though thread blocked. mean other methods may spend multiple main thread loop cycles blocked.
am right approach not ideal? preferred method of locking/unlocking?
you can count blocked threads own:
private long blockedcount = 0; private void fastloop() { lock (locker) { while (true) { dowork(); while (interlocked.read(ref blockedcount) > 0) monitor.wait(locker); } } } private void otherthreads() { try { var wasblocked = false; if (!monitor.tryenter(locker)) { wasblocked = true; interlocked.increment(ref blockedcount); monitor.enter(locker); } dosomethingelse(); if (wasblocked) interlocked.decrement(ref blockedcount); monitor.pulse(locker); } { monitor.exit(locker); } }
Comments
Post a Comment