Sharing Memory Between Two Applications

How to use Shared Memory between two separate applications in C

This is my solution using shmget, its outdated, but it works

Host:

#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{
char output[] = "test";
int shmid=shmget(IPC_PRIVATE, sizeof(output), 0666);
FILE *fp;
fp = fopen("/tmp/shmid.txt", "w+");
fprintf(fp, "%d", shmid);
fclose(fp);
int *mem_arr;

while(true)
{
mem_arr = (int *)shmat(shmid, NULL, 0);
memcpy(mem_arr, output, sizeof(output));
shmdt(mem_arr);
}
return 1;
}

Client:

#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{
char output[] = "test";
FILE *fp;
fp = fopen("/tmp/shmid.txt", "r");
int shmid;
fscanf (fp, "%d", &shmid);
fprintf(fp, "%d", shmid);
fclose(fp);

while(true)
{
int* shared_mem = (int *)shmat(shmid, NULL, 0);
printf("data: %s\n", shared_mem);
}
return 1;
}

Shared memory between 2 processes (applications)

Right now, .NET doesn't support sections (aka Memory Mapped Files). It will soon, the 4.0 version has the System.IO.MemoryMappedFiles namespace. There is a good reason it took so long and also the reason you are not going to be happy with this addition. Using pointers is mandatory in MMFs, the shared memory is made available at a specific address. To share a value, you'll have to write it to a specific address.

Pointers are however fundamentally incompatible with the managed memory model. Objects are created in a garbage collected heap, the collector moves them around as needed to keep the heap compacted. In a managed language, you have a reference to such an object, also knows as a "tracking handle". The C/C++ equivalent is a pointer, but it is one with bells on, the garbage collector can always find it back and update its value. The CLR does support the notion of "pinning", it converts a reference to a pointer. It implements this by marking the object as unmoveable. That however doesn't help implement shared memory through an MMF, the object is pinned in the GC heap instead of the virtual memory address where the MMF view is located.

To make an MMF work, the object needs to be copied from the GC heap to the shared memory. That requires serialization. The .NET 4.0 class is named MemoryMappedViewStream. You probably can see where this is going, this is indistinguishable from using a named pipe or a socket. Getting data in and out of an MMF takes the same amount of effort. An MMF is merely slightly more efficient because the underlying buffer is not in the kernel memory pool.

You can break the rulez and do so today. You can P/Invoke the CreateFileMapping, OpenFileMapping and MapViewOfFile you need to create an MMF. And use the unsafe keyword so you can create pointers. You'll need to use value types (like struct) for the shared memory elements or use the Marshal class.

C# memory shared between two Processes, can't get Read stream from one side

Solved.
The matter is about the.... "StreamWriter". I'm really sorry that It is not the IPC one. I figured out that StreamWriter should follow Close or flush. So I added "sw.Flush()"

static void Main(string[] args)
{
Console.WriteLine("임의의 정수를 입력해주세요");
int n =Convert.ToInt32(Console.ReadLine());
try
{
using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("test",MemoryMappedFileRights.Write))
{
using (MemoryMappedViewStream stream = mmf.CreateViewStream(0, (long)1e2))
{
StreamWriter sw = new StreamWriter(stream);

while (true)
{
sw.Write(n + " " );
Console.Write(n + " ");
if (n == 1) break;

if (n % 2 == 0) n /= 2;
else n = 3 * n + 1;
Thread.Sleep(500);
}
sw.Flush(); // <---- added
Console.WriteLine();
}
}
}
catch
{
while (true)
{
Console.Write("WHY IT DOESNT WORK????\n");
Thread.Sleep(500);
};
}
}

and It works well..

work well
sorry. I think my ask was not good enough to post. but I hope my ask, answer will help someone.

Sharing memory between two processes (C, Windows)

You can try a memory-mapped file.

This gives a bit more step-by-step detail.

Shared Memory between two JVMs

Solution 1:

The best solution in my opinion is to use memory mapped files. This allows you to share a region of memory between any number of process, including other non java programs. You can't place java objects into a memory mapped file, unless you serialize them. The following example shows that you can communicate between two different process, but you would need to make it much more sophisticated to allow better communication between the processes. I suggest you look at Java's NIO package, specifically the classes and methods used in the below examples.

Server:

public class Server {

public static void main( String[] args ) throws Throwable {
File f = new File( FILE_NAME );

FileChannel channel = FileChannel.open( f.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE );

MappedByteBuffer b = channel.map( MapMode.READ_WRITE, 0, 4096 );
CharBuffer charBuf = b.asCharBuffer();

char[] string = "Hello client\0".toCharArray();
charBuf.put( string );

System.out.println( "Waiting for client." );
while( charBuf.get( 0 ) != '\0' );
System.out.println( "Finished waiting." );
}
}

Client:

public class Client {

public static void main( String[] args ) throws Throwable {
File f = new File( FILE_NAME );
FileChannel channel = FileChannel.open( f.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE );

MappedByteBuffer b = channel.map( MapMode.READ_WRITE, 0, 4096 );
CharBuffer charBuf = b.asCharBuffer();

// Prints 'Hello server'
char c;
while( ( c = charBuf.get() ) != 0 ) {
System.out.print( c );
}
System.out.println();

charBuf.put( 0, '\0' );
}

}

Solution 2:

Another solution is to use Java Sockets to communicate back and forth between processes. This has the added benefit of allowing communication over a network very easily. It could be argued that this is slower than using memory mapped files, but I do not have any benchmarks to back that statement up. I won't post code to implementing this solution, as it can become very complicated to implement a reliable network protocol and is fairly application specific. There are many good networking sites that can be found with quick searches.


Now the above examples are if you want to share memory between two different process. If you just want to read/write to arbitrary memory in the current process, there are some warnings you should know first. This goes against the entire principle of the JVM and you really really should not do this in production code. You violate all safety and can very easily crash the JVM if you are not very careful.

That being said, it is quite fun to experiment with. To read/write to arbitrary memory in the current process you can use the sun.misc.Unsafe class. This is provided on all JVMs that I am aware of and have used. An example on how to use the class can be found here.



Related Topics



Leave a reply



Submit