i have created cross process event via manualresetevent. when event occur potentially n threads in n different processes should unblocked , start running fetch new data. problem seems manualresetevent.set followed immediate reset not cause waiting threads wake up. docs pretty vague there
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx
when state of manual-reset event object signaled, remains signaled until explicitly reset nonsignaled resetevent function. number of waiting threads, or threads subsequently begin wait operations specified event object, can released while object's state signaled.
there method called pulseevent seems need unfortunately flawed.
a thread waiting on synchronization object can momentarily removed wait state kernel-mode apc, , returned wait state after apc complete. if call pulseevent occurs during time when thread has been removed wait state, thread not released because pulseevent releases threads waiting @ moment called. therefore, pulseevent unreliable , should not used new applications. instead, use condition variables.
now ms recommend use condition variables.
condition variables synchronization primitives enable threads wait until particular condition occurs. condition variables user-mode objects cannot shared across processes.
following docs seem have run out of luck reliably. there easy way accomplish same thing without stated limitations 1 manualresetevent or need create each listener process response event ack each subscribed caller? in case need small shared memory register pids of subscribed processes seems bring in own set of problems. happen when 1 process crashes or not respond? ....
to give context. have new state publish other processes should read shared memory location. ok miss 1 update when several updates occur @ once process must read @ least last date value. poll timeout seems not correct solution.
currently down to
changeevent = new eventwaithandle(false, eventresetmode.manualreset, countername + "_event"); changeevent.set(); thread.sleep(1); // increase odds release waiters changeevent.reset();
one general purpose option handling case producers must wake consumers , number of consumers evolving use moving fence approach. option requires shared memory ipc region too. method result in consumers being woken when no work present, if lots of processes need scheduling , load high, wake except on hopelessly overloaded machines.
create several manual reset events , have producers maintain counter next event set. events left set, except nexttofire event. consumer processes wait on nexttofire event. when producer wishes wake consumers resets next+1 event , sets current event. consumers scheduled , wait on new nexttofire event. effect producer uses resetevent, consumers know event next wake them.
all users init: (pseudo code c/c++, not c#)
// create shared memory , initialise nexttofire; psharedmemory = mapmysharedmemory(); if (first create memory) psharedmemory->nexttofire = 0; handle array[4]; array[0] = createevent(null, 1, 0, "event1"); array[1] = createevent(null, 1, 0, "event2"); array[2] = createevent(null, 1, 0, "event3"); array[3] = createevent(null, 1, 0, "event4");
producer wake all
long currentndx = psharedmemory->nexttofire; long nextndx = (currentndx+1) & 3; // reset next event consumers block resetevent(array[nextndx]); // flag consumers new value long actual = interlockedincrement(&psharedmemory->nexttofire) & 3; // next line needed if multiple producers active. // not perfect solution if (actual != nextndx) resetevent(actual); // wake them setevent(currentndx);
consumers wait logic
long currentndx = (psharedmemory->nexttofire) & 3; waitforsingleobject(array[currentndx], timeout);
Comments
Post a Comment