mmap and msync things in c
I'm programming with C in linux. I'm having some mysterious problems with one program that is trying to use a mapped memory with some speed, so I'm trying to guess what could be happening:
The manpages tell that when a program writes something in mapped memory, the bits don't necessarily show in the file before msync is called. My question deals with the other direction: When a program reads something from a mapped memory, is it really reading the bits from the file for sure? Is there something that should be done to ensure that the possibly updated file's contents are showing in the memory?
It seems that my problem was that the memory updating was actually occurring faster than I assumed. The program was assuming that file would be updated only when msync is called, which lead to the problems, because the file was being updated already before msync automatically.
In any case. If somebody has firm words of knowledge to my original question, I'm still listening.
In any case. If somebody has firm words of knowledge to my original question, I'm still listening.
Quote:Original post by jostpuurIf you memory map a file and modify a memory page, the changes will be written back at an unknown time. Your only guarantees are that changes will be on the disk either after munmap() returns, or after msync(...., MS_SYNC) returns. Please do note that MS_SYNC will kill most if not all performance advantages that you get from memory mapping.
The manpages tell that when a program writes something in mapped memory, the bits don't necessarily show in the file before msync is called. My question deals with the other direction: When a program reads something from a mapped memory, is it really reading the bits from the file for sure? Is there something that should be done to ensure that the possibly updated file's contents are showing in the memory?
However, this doesn't really matter for sharing mappings, because the different mappings will have the same physical memory, so as soon as you write to it from one mapping, it must change in all others too, whether it's flushed to disk or not. There's really no way around, as it is the very same physical memory (except if you're using MAP_PRIVATE of course, in this case the OS will silently make a copy).
The one situation where syncing really does matter is if you have to anticipate a power failure or server crash because you're doing reliable transactions for a database, or something the like.
Or, if you memory map a file and read from / write to using normal file access at the same time, which is obviously a terribly bad idea from the beginning. Other than that, forget about it... it'll just work somehow, and it's not your problem. The OS has to make sure it works.
Quote:Original post by samoth
However, this doesn't really matter for sharing mappings, because the different mappings will have the same physical memory, so as soon as you write to it from one mapping, it must change in all others too, whether it's flushed to disk or not.
I was using mmap with flag MAP_SHARED, for the purpose of getting communication between forked processes. This means that the file, that is used in memory mapping, is actually redundant? Is it possible to have common memory for processes without use of any file?
I've hidden the file with a kind of name ./.tmp_file0, and the program destroys the file when quitting, so the effect is now probably the same that it would be without the file existing at all. But this looks complicated way of doing something now.
Quote:Original post by jostpuur
Is it possible to have common memory for processes without use of any file?
Unless I have misunderstood something about your question, see man shmat.
For further reference. If you know of functionality similiar to what you are after, checking the SEE ALSO part of its man page often leads you in the right direction.
I use the following code to create a private mapping without a temporary file:
For your purpose you probably just have to replace MAP_PRIVATE with MAP_SHARED.
void * buf = 0;int fdDevZero = open("/dev/zero", O_RDWR);if (mFdDevZero != -1){ buf = mmap(0, maxBytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_NORESERVE, fdDevZero, 0); if (buf == MAP_FAILED) { buf = 0; close(fdDevZero); fdDevZero = -1; }}
For your purpose you probably just have to replace MAP_PRIVATE with MAP_SHARED.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement