2016-02-24 10 views
6

Sono nuovo a multitasking e IPC e sto cercando di costruire un approccio per la comunicazione inter processo veloce utilizzando la memoria condivisa (inizialmente stavo ricercando il termine IPC, avendo in mente wcfsockets e named pipes solo per scoprire infine su MMF).implementazione di un processo intermedio Fast .NET Fast-Free con SharedMemory MMF

Ora che ho implementato con successo un piccolo test utilizzando la memoria condivisa tra due processi tramite l'utilizzo della segnalazione Lock e EventWaitHandle, sono fino a un approccio che implementa un modello di non blocco/non attesa. Ora, sto cercando di combinare Thread.MemoryBarrier() & leggendo un signalling Sector dal MemoryMapedFile.

Il problema non è identificato! Primo turno passa attraverso e il secondo è stato lo scorso situati nel triangolo delle Bermuda ... fuori dal campo di applicazione del debugger ...

dicono processo un è l'invio di una raffica di richieste di un showMsg() a processo b.

          //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;} 
} 

Mentre stavo prima utilizzando la soluzione in filodiffusione nome, l'approccio Mmf (nonostante Lock e Evento Wait Handle) è stato grande guadagno di prestazioni rispetto all'approccio NamedPipe, ma potrei anche andare oltre utilizzando l'approccio di cui sopra in qualche modo ..?

potrei semplicemente clonare questo modello come striping Raid ...

Reader1 + Reader2 & WriteThred1 + WriteThread2 

così ho provato ed è rimasto bloccato in quel punto.

È questo approccio valido che utilizza la memoria condivisa & sharedmemory per la segnalazione?

Se è così, non resta che capire perché la seconda iterazione è fallita, la differenza di prestazioni.

EDIT - ha aggiunto la logica dietro alla prova le discussioni in più

Questo è il "ponte" che sto usando per manipolare le discussioni scrittore (lo stesso approccio per i lettori

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(); 
} 

Usando la maniglia di scrittura. leggere & scrivere i dati reali (codice simile per la scrittura)

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; 
} 

Come ho Detto questo, ho ricercato questo problema di sincronizzazione dei dati e della memoria condivisa tramite blocchi non bloccanti/no-wait/ecc. Semaphores Locks, quindi sto cercando di rimuovere qualsiasi tipo di sovraccarico durante il processo di ciascuna transazione di dati nella memoria condivisa mappata file. Sono qui per chiedere quale potrebbe essere il problema eliminando Lock And The EventWaitHandle e sostituendolo con la logica delle recinzioni di memoria e segnalando attraverso il mmf?

+4

Non vedo davvero perché questo ha ottenuto tre upvotes in un minuto (probabilmente perché "ooh cool, file mappati in memoria"); potresti forse spendere qualche sforzo per capitalizzare correttamente e applicare la punteggiatura alle tue frasi e provare a spiegare passo passo cosa dovrebbe fare questo codice e dove smette di fare ciò che ti aspetti? Non ne sono del tutto sicuro, ma penso che mostrare un codice reale al posto di questo pseudocodice potrebbe anche aiutare. – CodeCaster

+0

@CodeCaster non essere un commentatore al gusto di limone, cerca di essere positivo (:, pubblicherò un po 'di codice che riguarda il secondo set di thread ho pensato che sia irrilevante – RalfL

+1

Nessun problema, penso _ hai una domanda abbastanza interessante sul tuo mani qui, so un po 'di threading e file mappati in memoria, è solo che è molto difficile capire la vera domanda.Tutto questo.Tram – CodeCaster

risposta

0

Se si prevede di utilizzarlo per uno scopo specifico diverso da R & D, il modo più semplice sarebbe utilizzare una libreria che già lo fornisce. Un modo per pensarci è Lock free = Message Passing. Due possibili approcci sono: Per un'implementazione di passaggio di messaggi minimalista, ZeroMQ IPC, che fornisce grandi prestazioni.Supporto netto e prestazioni IPC superbe (http://www.codeproject.com/Articles/488207/ZeroMQ-via-Csharp-Introduction) e per un'implementazione di Actor-Model più completa (incluso il supporto per IPC), consultare Akka.net (http://getakka.net/docs/#networking).

Se lo scopo è più R & D in natura (significato, si desidera scrivere una propria implementazione, che è cool), vorrei ancora suggerire di guardare la fonte di questi prodotti (in particolare, Akka.net , dal momento che è scritto in C#), per idee di implementazione su Message-passing e IPC basato su attore.

Problemi correlati