Hi All,
I am trying to write code to sync between processes. Here is the piece of code:
setSignal(); // signal me (WaitHandle) first
if (!WaitHandle.WaitAll(mWaitHandles, timeout_ms, true)) // mWaitHandles is an array of named event handles
{
mLog.WriteLine("While wait for sync, it's timed out."); // better not reach here, so timeout_ms should be big
}
resetSignal(); // reset WaitHandle
My problem is that because setSignal() and WaitHandle.WaitAll() is not atomic, other processes could have reset Signal before I enter WaitAll(), then I have a deadlock or timeout. So I need a SignalAndWait() similar method SignalAndWaitAll(). Is there such construct? If not, can I create one?
Thanks for your consideration.
Loading
H XiaPosted Sep 1, 2009, 2:27 PM
Considering there is no such construct, will the following code work for such scenario?
Assume all the event handle instances are validly constructed and the thread is started properly.
public sealed class X : CriticalFinalizerObject, IDisposable
{
EventWaitHandle mEWH = null; // WaitHandle created by this instance
// the following two fields pair each other
WaitHandle[] mWaitHandles = null; // WaitHandles created by other instances
string[] mEventName4WaitHandles = null; // EventName for WaitHandles created by other instances
// using thread to reset signal
bool mRunPostSetSignalThread = true;
// event to signal setSignal myself
EventWaitHandle mEWH4PostSetSignal = null;
...
static void PostSetSignalThreadFunc(Object state)
{
for (; mRunPostSetSignalThread; mEWH4PostSetSignal.Reset())
{
mEWH4PostSetSignal.WaitOne();
Thread.Sleep(1); // switch context to make sure the main thread entering wait state
// is there any way to know whether the main thread is in waiting status?
mEWH.Set();
}
}
public void synchronize(int timeout_ms)
{
while (mEWH4PostSetSignal.WaitOne(0, false))
{
mLog.WriteLine("mEWH4PostSetSignal needs to signal, but it's already in signaled state."); // should not reach here, so timeout_ms should be big
Thread.Sleep(1); // should not be here. Just let other threads run so mEWH4PostSetSignal is reset.
}
mEWH4PostSetSignal.Set(); // post setSignal() to make sure entering WaitAll before _SinglePCSync signaled
// we always try to guarantee that the WaitAll is done before self is signaled.
if (!WaitHandle.WaitAll(mWaitHandles, timeout_ms, true))
{
mLog.WriteLine("While wait for sync, it's timed out."); // better not reach here, so timeout_ms should be big
}
Thread.Sleep(1); // Just let other threads run ahead of resetSignal.
while (!mEWH.WaitOne(0, false)) // make sure mEWH is set before we reset it
{
mLog.WriteLine("mEWH needs to reset signal, but it's already in reset state."); // better not reach here, so timeout_ms should be big
Thread.Sleep(1); // normally it should not be here
}
mEWH.Reset();
}
}
H XiaPosted Aug 4, 2009, 4:08 PM
Unfortunately, what I need is the sync between processes. Monitor is just, as far as I know, CriticalSection, it's valid only in a process.
Roei BarPosted Aug 3, 2009, 3:55 PM
here is a sample:
Monitor.Wait/Pulse/PulseAll can be used insted of the primitive WaitforSignalMonitor.Waitatomically releases the lock and waits, reacquiring the lock before it returns