Memoria condivisa tra 2 processi (applicazioni)

Non riesco a trovare alcuna risposta utile a questa domanda, sebbene sia stata chiesta in modo diverso più volte.

Voglio condividere una memoria tra due processi (due diverse applicazioni), in modo che uno di loro possa scrivere su quella memoria e l’altro possa leggere.

È ansible in .NET? Come?

Grazie

Al momento, .NET non supporta sezioni (ovvero file mappati in memoria). Presto, la versione 4.0 avrà lo spazio dei nomi System.IO.MemoryMappedFiles. C’è una buona ragione per cui ci è voluto così tanto tempo e anche il motivo per cui non sarai contento di questa aggiunta. L’utilizzo dei puntatori è obbligatorio negli MMF, la memoria condivisa è resa disponibile a un indirizzo specifico. Per condividere un valore, dovrai scriverlo su un indirizzo specifico.

I puntatori sono tuttavia fondamentalmente incompatibili con il modello di memoria gestita. Gli oggetti vengono creati in un heap di garbage collection, il collector li sposta in base alle necessità per mantenere compatto l’heap. In un linguaggio gestito, hai un riferimento a tale object, noto anche come “handle di tracciamento”. L’equivalente C / C ++ è un puntatore, ma è uno con le campane su, il garbage collector può sempre ritrovarlo e aggiornarne il valore. Il CLR supporta la nozione di “pinning”, converte un riferimento in un puntatore. Implementa ciò contrassegnando l’object come non amovibile. Ciò tuttavia non aiuta a implementare la memoria condivisa attraverso un MMF, l’object è bloccato nell’heap GC invece dell’indirizzo di memoria virtuale in cui si trova la vista MMF.

Per far funzionare un MMF, è necessario copiare l’object dall’heap GC alla memoria condivisa. Ciò richiede la serializzazione. La class .NET 4.0 è denominata MemoryMappedViewStream. Probabilmente puoi vedere dove sta andando, questo non è distinguibile dall’uso di una named pipe o socket. Ottenere dati dentro e fuori da un MMF richiede lo stesso sforzo. Un MMF è solo leggermente più efficiente perché il buffer sottostante non si trova nel pool di memoria del kernel.

Puoi rompere la regola e farlo oggi. È ansible P / Richiamare CreateFileMapping, OpenFileMapping e MapViewOfFile per creare un file MMF. E utilizzare la parola chiave non sicura in modo da poter creare puntatori. Avrai bisogno di usare tipi di valore (come struct) per gli elementi di memoria condivisa o usare la class Marshal.

IPC

Se stai parlando di Inter Process Communication. Ci sono diverse possibilità come l’uso di socket tcp / udp, mailslot, named pipe, file mappati in memoria, messaggi windows, ecc.

.Net offre anche alcuni IPC di livello superiore come .Net remote e WCF che utilizzano le tecniche menzionate in precedenza. Puoi leggere di più qui .

File mappati in memoria

Se vuoi davvero condividere un blocco di memoria invece di comunicare, forse i file mappati in memoria sono ciò che desideri. .Net 4.0 ha MemoryMappedFile per quello. Se non lo usi o non riesci a utilizzare .Net 4.0, potresti implementarlo tu stesso come in questo esempio di win32 . Oppure puoi provare questo codice o vedere se puoi usare MemoryMappedFileStream menzionato qui e qui . Oppure usa questa class FileMap .

Utilizzare una pipe denominata .

È un meccanismo che consente a un processo di scrivere dati sequenziali in uno stream, da cui l’altro processo può leggere.

Si noti che named pipe consente solo la lettura sequenziale. Se è necessario utilizzare query più elaborate, è ansible che si desideri utilizzare l’architettura client-server. In questo caso, il processo del lettore interroga l’altro processo per informazioni utilizzando i socket di rete .

Come già accennato, utilizzare i file mappati in memoria. Implementazione per .NET <4 disponibile all'indirizzo: http://github.com/tomasr/filemap/
Ho usato e funziona in modo impeccabile. Potresti avere alcuni problemi di sicurezza durante la condivisione tra processi elevati / non elevati – la soluzione è di inizializzare il file mappato in memoria nel processo elevato e impostare di conseguenza gli attributi di sicurezza.