I want to implement the fastest possible Inter-Process Communication (IPC) (least CPU bound) between 2 .NET Core (or even mono possible) applications on Linux (SBC).
I tried TPC (socket, loopbacks) and anonymous/named pipes which are way too slow. Now I am testing MemoryMappedFiles (shared memory) and I am observing kind of strange behavior.
The next code works for me fine:
static async Task Main(string[] args)
{
var are = new AutoResetEvent(false);
var masterTask = Task.Run(async () =>
{
using (var memoryMappedFile = MemoryMappedFile.CreateNew("test", 100_000))
{
using (var memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor())
{
are.Set();
for (int i = 0; i < 100; i++)
{
Console.WriteLine($"Master: {i}");
memoryMappedViewAccessor.Write(0, i);
await Task.Delay(1000);
}
}
}
});
are.WaitOne();
var slaveTask = Task.Run(async () =>
{
using (var memoryMappedFile = MemoryMappedFile.OpenExisting("test"))
{
using (var memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor())
{
int number;
do
{
number = memoryMappedViewAccessor.ReadInt32(0);
Console.WriteLine($"Slave: {number}");
await Task.Delay(1000);
}
while (number < 99);
}
}
});
await Task.WhenAll(masterTask, slaveTask);
Console.WriteLine("...");
Console.ReadKey();
}
But when I split it into 2 applications:
static async Task Main(string[] args)
{
using (var memoryMappedFile = MemoryMappedFile.CreateNew("test", 100_000))
{
using (var memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor())
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine($"Master: {i}");
memoryMappedViewAccessor.Write(0, i);
await Task.Delay(1000);
}
}
}
Console.WriteLine("...");
Console.ReadKey();
}
and
static async Task Main(string[] args)
{
using (var memoryMappedFile = MemoryMappedFile.OpenExisting(mapName: "test"))
{
using (var memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor())
{
int number;
do
{
number = memoryMappedViewAccessor.ReadInt32(0);
Console.WriteLine($"Slave: {number}");
await Task.Delay(1000);
}
while (number < 99);
}
}
Console.WriteLine("...");
Console.ReadKey();
}
the second "client" app return:
Unhandled Exception: System.IO.FileNotFoundException: at System.IO.MemoryMappedFiles.MemoryMapImpl.OpenFile (System.String path, System.IO.FileMode mode, System.String mapName, System.Int64& capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access, System.IO.MemoryMappedFiles.MemoryMappedFileOptions options) [0x00065] in :0
Why is it? Could I somehow let the second app see the resources of the first one?
(Note: Not sure 100% but I can bet I was able to run such 2 apps previously - several years ago - on mono - I wish it was true and there is a way).
Another thought brings me to the idea of whether there is any C++ tool to do so, that can be wrapped from c# to do so. Is it possible?