C to C # (Mono), memory-mapped files / shared memory in Linux
I am working on an embedded system that consumes about 20 megs of data per second. My low-level collection, management and processing layer converts most of it into several important values, but it can also be useful for the end user to get an idea of ββthe raw data window.
I am working on ASP.NET frontend in C # with mod-mono. I would like the ASP.NET page server side to be able to request the last half second or so easily. C ++ code has real-time constraints, so I can't use message passing to respond - it can easily get bogged down by too many clients or someone quickly refreshed. I would like it to be able to post data somewhere where any number of C # readers can access it as needed.
I represent a shared memory area with a rolling buffer of at least 16 or 32 MB of data. The C ++ code is constantly updating it and the C # code can look into it whenever it wants. Is there a way to handle this? All the information I find when using memory mapped files seems to focus on expanding the child, instead of using two unrelated processes for IPC - whether to push to disk (or fs cache, etc.) Before the C # application sees this, or does the map display from the two programs actually force them to share the same pages?
Is there a way to access POSIX shared memory objects in C #?
source to share
Here's an example with information on sharing C and C # programs (two different processes) using a memory mapped file:
-
From the console create file: dd if = / dev / zero of = / tmp / sharedfile bs = 12288 count = 1
-
C # program:
using System; using System.IO; using System.IO.MemoryMappedFiles; using System.Threading; namespace FileSharedMemory { class MainClass { public static void Main (string[] args) { using (var mmf = MemoryMappedFile.CreateFromFile("/tmp/sharedfile", FileMode.OpenOrCreate, "/tmp/sharedfile")) { using (var stream = mmf.CreateViewStream ()) { // 1. C program, filled memory-mapped file with the 'G' character (200 characters) var data = stream.ReadByte (); while (data != -1) { Console.WriteLine ((char)data); data = stream.ReadByte (); } // 2. We write "Goose" at the beginning of memory-mapped file. stream.Position = 0; var buffer = new byte[] { 0x47, 0x6F, 0x6F, 0x73, 0x65 }; stream.Write (buffer, 0, 5); Thread.Sleep (20000); // 3. C program, filled memory-mapped file with the 'H' character (200 characters) stream.Position = 0; data = stream.ReadByte (); while (data != -1) { Console.WriteLine ((char)data); data = stream.ReadByte (); } } } } } }
-
Program C:
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/mman.h> #include <errno.h> int main(int argc, char *argv[]) { int fd; int index; char *data; const char *filepath = "/tmp/sharedfile"; if ((fd = open(filepath, O_CREAT|O_RDWR, (mode_t)00700)) == -1) { perror("open"); exit(EXIT_FAILURE); } data = mmap(NULL, 12288, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } for (index= 0; index < 200; index++) { data[index] = 'G'; } sleep(10); // We must see 'Goose' at the beginning of memory-mapped file. for (index= 0; index < 200; index++) { fprintf(stdout, "%c", data[index]); } for (index= 0; index < 200; index++) { data[index] = 'H'; } if (msync(data, 12288, MS_SYNC) == -1) { perror("Error sync to disk"); } if (munmap(data, 12288) == -1) { close(fd); perror("Error un-mmapping"); exit(EXIT_FAILURE); } close(fd); return 0; }
source to share