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 #?

+3


source to share


1 answer


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

+6


source







All Articles