Memory Mapped File Mutex Problem
i have 2 programs need communicate each other. 1 windows service (which runs constantly) , other wcf web api has short ttl. dont think types of programs here make difference in trying do.
the first program windows service - running
mutex mutex; memorymappedfile mmf; int m_ioffset = 0; int m_ilength = 255; byte[] m_bybuffer; bool mutexcreated; private void form1_load(object sender, eventargs e) { mutex = new mutex(true, "mmf_ipc", out mutexcreated); mmf = memorymappedfile.createoropen("testapplication", m_ilength); } private void button1_click(object sender, eventargs e) { m_bybuffer = new byte[m_ilength]; m_bybuffer = tobytes(textbox1.text); using (var accessor = mmf.createviewaccessor(m_ioffset, m_bybuffer.length)) { accessor.writearray<byte>(0, m_bybuffer, m_ioffset, m_bybuffer.length); } mutex.releasemutex(); } private byte[] tobytes(string str) { byte[] bytes = new byte[str.length * sizeof(char)]; system.buffer.blockcopy(str.tochararray(), 0, bytes, 0, bytes.length); return bytes; } the second program wcf api - incremental calls whenever user needs
int m_ioffset = 0; int m_ilength = 255; private void button1_click(object sender, eventargs e) { byte[] buffer = new byte[m_ilength]; using (var mmf = memorymappedfile.openexisting("testapplication")) { using (var accessor = mmf.createviewaccessor(m_ioffset, buffer.length)) { mutex mutex = mutex.openexisting("mmf_ipc"); mutex.waitone(); accessor.readarray<byte>(0, buffer, 0, buffer.length); } } string str = system.text.encoding.default.getstring(buffer); messagebox.show(str); } they can communicate not reliable.
sometimes program hangs, "object synchronization method called unsynchronized block of code." on mutex.releasemutex();
what missing? (thanks in advance help!)
here's basic solution using semaphores (i tend prefer them on events in case):
class program { static void main() { var writer = new thread(writer); var reader = new thread(reader); writer.start(); reader.start(); console.readline(); } static void writer() { var mmf = memorymappedfile.createoropen("testapplication", 4096); var view = mmf.createviewaccessor(); // semaphore used signal shared memory empty var empty = new semaphore(1, 1, "mmf_empty"); // semaphore used signal shared memory full var full = new semaphore(0, 1, "mmf_full"); var = 0; while (true) { var message = encoding.utf8.getbytes(string.format("message {0}", i++)); // wait shared memory empty empty.waitone(); // write length of message , message view.write(0, message.length); view.writearray(4, message, 0, message.length); // signal reader have placed message in shared memory full.release(); } } static void reader() { var mmf = memorymappedfile.createoropen("testapplication", 4096); var view = mmf.createviewaccessor(); var empty = new semaphore(1, 1, "mmf_empty"); var full = new semaphore(0, 1, "mmf_full"); var buffer = new byte[1024]; while (true) { // wait message placed in shared memory full.waitone(); // read message int length = view.readint32(0); view.readarray(4, buffer, 0, length); // signal writer can place message in shared memory empty.release(); console.writeline(encoding.utf8.getstring(buffer, 0, length)); thread.sleep(100); } } } i'm using 2 threads in same process sake of simplicity should work processes. note allows 1 message put in shared memory @ time. allow more messages need keep track of write offset , read offset (both stored in shared memory), allows create circular buffer. if need multiple reader/writer threads you'll need additional synchronization (in form of mutex or perhaps interlocked operations) prevent multiple readers/writers modifying shared memory @ same time.
Visual Studio Languages , .NET Framework > Visual C#
Comments
Post a Comment