On Sun, 15 Oct 2006, Nicholas Frechette wrote:
Hi, I’m currently working on a side project which has me store binary
content in memory. In order to make it’s use as transparent as possible, i
overloaded the ‘require’ method to search as well in the memory and this
works fine at the moment. In the same line of thought, I tried changing the
way File.new works to return a StringIO object pointing to my binary data in
memory instead of an ordinary IO object… However, i ran into an
interesting problem. Consider the following code:
the way to accomplish this is to use mmap. that’s what the call
basically
does: map file to memory and return them as strings. if you create more
than
one mapping you will not map the file twice (if you give the right flags
to
the ctor). here’s a little example of using mmap to modify the running
program:
here’s the program
harp:~ > cat a.rb
require 'mmap'
mmap = Mmap.new __FILE__, 'rw', Mmap::MAP_SHARED
mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
mmap.msync
mmap.munmap
p DATA.readlines
__END__
here’s one run
harp:~ > ruby a.rb
["{#<Mmap:0xb75cc79c>=>\"1160922660.6115\"}\n"]
harp:~ > cat a.rb
require 'mmap'
mmap = Mmap.new __FILE__, 'rw', Mmap::MAP_SHARED
mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
mmap.msync
mmap.munmap
p DATA.readlines
__END__
{#<Mmap:0xb75cc79c>=>"1160922660.6115"}
here’s the next
harp:~ > ruby a.rb
["{#<Mmap:0xb75cc79c>=>\"1160922660.6115\"}\n",
“{#Mmap:0xb75d079c=>“1160922666.11629”}\n”]
harp:~ > cat a.rb
require 'mmap'
mmap = Mmap.new __FILE__, 'rw', Mmap::MAP_SHARED
mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
mmap.msync
mmap.munmap
p DATA.readlines
__END__
{#<Mmap:0xb75cc79c>=>"1160922660.6115"}
{#<Mmap:0xb75d079c>=>"1160922666.11629"}
as many times as you might call " Mmap.new FILE, ‘rw’,
Mmap::MAP_SHARED "
your process will only have one mapping. in fact, you really cannot map
it
more times:
harp:~ > cat a.rb
require 'mmap'
mmaps = Array.new(3){ Mmap.new __FILE__, 'rw', Mmap::MAP_SHARED }
mmaps.each do |mmap|
mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
mmap.msync
mmap.munmap
end
p DATA.readlines
__END__
harp:~ > ruby a.rb
["{#<Mmap:0xb75d179c>=>\"1160922968.42437\"}\n"]
harp:~ > cat a.rb
require 'mmap'
mmaps = Array.new(3){ Mmap.new __FILE__, 'rw', Mmap::MAP_SHARED }
mmaps.each do |mmap|
mmap << { mmap => Time.now.to_f.to_s }.inspect << "\n"
mmap.msync
mmap.munmap
end
p DATA.readlines
__END__
{#<Mmap:0xb75d179c>=>"1160922968.42437"}
notice how the second and third calls were no-ops. that’s because all
three
mappings were actually the same, and unmapping the first unmapped the
rest -
leaving the rest of the loops as no-ops.
regards.
-a