2016-02-24 1 views
6

Я новичок в multitasking и IPC, и я пытаюсь построить подход для быстрого взаимодействия между процессами с использованием общей памяти (сначала я изучал термин IPC, имея в виду wcfsockets и named pipes, чтобы в конечном итоге узнать о MMF).Внедрение Fast .NET Lock-Free Inter-Process с использованием SharedMemory MMF

Теперь, когда я успешно выполнил небольшой тест, используя разделяемую память между двумя процессами, используя сигнализацию Lock и EventWaitHandle, я подхожу к подходу, который реализует шаблон без блокировки/отсутствия ожидания. Теперь, я пытаюсь совместить Thread.MemoryBarrier() & с signalling Sector от MemoryMapedFile.

Проблема не установлена! Первый раунд проходит и второй последний был расположен в Бермудском треугольнике ... выходит за рамки отладчика ...

говорит способ а посылает всплеск запросов на showMsg() для процесса б.

          //offset positions in mmf 
MemoryMappedViewAccessor MmfAcc; const int opReady= 0, opCompleteRead = 4, ..... 



ReadTrd() 
{ 
    //[0,3] - Reader is stationed 
    //[4,7] - Read Complete successfully 
    //[8,11] - Data-size 
    //[12,15] - Reader-exiting 
    "format" the signals Section (write zeroes). 

    for(;;){if (WrTrd-StepMMF1 Confimed) break;} 
    MmfAcc- read DataSize val @offset[8] 
    MmfAcc- read Data val @offset[50] 
    MmfAcc Write exit to offset.... 
    ....heavy use of Thread.MemoryBarrier(); sets !!! (all over the place, on every shared variable...) 

} 

writeTrd() 
{ 
    heavy use of Thread.MemoryBarrier() !!! 
    //[15-19] - wr is stationed 
    //[20-23] - wr Complete successfully 
    //[24-27] - wrExiting 
    "format" the signals Section . 
    for(;;){if Reader-StepMMF1 is Confim break;} 
    MmfAcc- DataSize to offset[8] 
    write Data To offset[50] using the method below 
    for(;;){if Read StepMMF2 is Confim break;} 
} 

Как я был первым использование имени водопроводного решения, подхода MMF (несмотря на Lock и событие Подождите Handle) был большой приростом производительности по сравнению с именованным каналом подхода, но я мог пойти еще дальше, используя вышеупомянутый подход как-то ..?

Я мог бы просто клонировать эту модель, как чередование Raid ...

Reader1 + Reader2 & WriteThred1 + WriteThread2 

поэтому я попробовал и застрял в этой точке.

Действительно ли этот подход используется с полной памятью & sharedmemory для сигнализации?

Если это так, все осталось увидеть, почему вторая итерация не удалась, разница в производительности.

EDIT - добавил логику теста дополнительных нитей

Это «мост» Я использую, чтобы манипулировать писатель темы (тот же подход для читателей

public void Write(byte[] parCurData) 
{ 
    if (ReadPosition < 0 || WritePosition < 0) 
     throw new ArgumentException(); 
    this.statusSet.Add("ReadWrite:-> " + ReadPosition + "-" + WritePosition); 
    // var s = (FsMomitorIPCCrier)data; 

    ////////lock (this.dataToSend) 
    ////////{ 
    Thread.MemoryBarrier(); 
     LiveDataCount_CurIndex = dataQue.Where(i => i != null).Count(); 
    this.dataQue[LiveDataCount_CurIndex] = parCurData; 

    Console.WriteLine("^^^^^" + Thread.CurrentThread.Name + " has Entered WritingThreads BRIDGE"); 
    Console.WriteLine("^^^^^[transactionsQue] = {1}{0}^^^^^[dataQue.LiveDataASIndex = {2}{0}^^^^^[Current Requests Count = {3}{0}", "\r\n", Wtransactions, LiveDataCount_CurIndex, ++dataDelReqCount); 

    //this.itsTimeForWTrd2 = false; 

    if (Wtransactions != 0 && Wtransactions > ThrededSafeQ_Initial_Capcity - 1) 
    if (this.dataQueISFluded) this.DataQXpand(); 


    if (itsTimeForWTrd2) 
    { 

     bool firstWt = true; 
     while (writerThread2Running) 
     { 
      if (!firstWt) continue; 
      Console.WriteLine("SECOND WRITERThread [2] is In The CoffeeCorner"); 
        firstWt=false; 
     } 

     this.dataDelivery2 = this.dataQue[LiveDataCount_CurIndex]; 
     Console.WriteLine("Activating SECOND WRITERThread [2]"); 
     itsTimeForWTrd2 = false; 

     writerThread2Running = true; 
     //writerThread1Running = true; 
     writerThread2 = new System.Threading.Thread(WriterThread2); 
     writerThread2.IsBackground = true; 
     writerThread2.Name = this.DepoThreadName + "=[WRITER2]"; 
     writerThread2.Start(); 

    } 
    else 
    { 
     bool firstWt = true; 
     while (writerThread1Running) 
     { 
      if (!firstWt)continue; 
       Console.WriteLine("WRITERThread [1] is In The CoffeeCorner"); 
      firstWt=false; 
     } 
     Console.WriteLine("Activating WRITERThread [1]"); 
     this.dataDelivery1 = this.dataQue[LiveDataCount_CurIndex]; 

     writerThread1Running = true; 
     writerThread1 = new System.Threading.Thread(WriterThread1); 
     writerThread1.IsBackground = true; 
     writerThread1.Name = this.DepoThreadName+"=[WRITER1]"; 
     writerThread1.Start(); 
     itsTimeForWTrd2 = true; 

    } 
    Thread.MemoryBarrier(); 
} 

Используя ручку записи. читать & писать фактические данные (аналогичный код для записи)

public unsafe byte[] UsReadBytes(int offset, int num) 
{ 
    byte[] arr = new byte[num]; 
    byte* ptr = (byte*)0; 
    this.accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr); 
    Marshal.Copy(IntPtr.Add(new IntPtr(ptr), offset), arr, 0, num); 
    this.accessor.SafeMemoryMappedViewHandle.ReleasePointer(); 
    return arr; 
} 

в I сказал, я исследовал эту проблему синхронизации данных и разделяемой памяти через неблокирующие/не-ждущие/и т. д. Семафоры Locks, поэтому я пытаюсь удалить любые накладные расходы в процессе каждой транзакции данных в карту памяти, отображаемую файл. Я здесь, чтобы спросить, что может быть проблемой, устраняющей Lock And The EventWaitHandle и заменяя ее логикой памяти и сигнализацией через mmf?

+4

Я действительно не понимаю, почему в течение минуты у него появилось три upvotes (ну, вероятно, потому что «ooh cool, файлы с отображением памяти»); не могли бы вы потратить некоторое время на то, чтобы правильно использовать и применять пунктуацию к своим предложениям и пытаться объяснить шаг за шагом, что этот код должен делать, и где он перестает делать то, что вы ожидаете? Я не совсем уверен, но я думаю, что показ некоторого фактического кода вместо этого псевдокода также может помочь. – CodeCaster

+0

@CodeCaster не является комментарием с ароматом лимона, постарайтесь быть позитивным (:, я отправлю еще несколько кодов с участием второго набора потоков. Я думал, что это нерелевантно – RalfL

+1

Нет проблем, я _think_ у вас есть довольно интересный вопрос на вашем руки здесь, я немного знаю о потоках и файлах с отображением памяти, просто очень сложно выяснить реальный вопрос. Вот и все. – CodeCaster

ответ

0

Если вы планируете использовать это для определенной цели, кроме R & D, самым простым способом было бы использовать библиотеку, которая уже предоставляет это. Один из способов подумать об этом - Lock Free = Message Passing. Двумя возможными подходами являются: для минималистической реализации передачи сообщений ZeroMQ IPC, которая обеспечивает отличные результаты.Чистая поддержка и превосходная производительность IPC (http://www.codeproject.com/Articles/488207/ZeroMQ-via-Csharp-Introduction), а также для более полной реализации Actor-Model (включая поддержку IPC), посмотрите на Akka.net (http://getakka.net/docs/#networking).

Если цель более R & D в природе (смысл, вы хотите написать собственную реализацию, которая круто), я бы предложил посмотреть на источник этих продуктов (особенно, Akka.net , так как он написан на C#), для реализации идей о передаче сообщений и IPC на основе Actor.