Cuando se trata de comunicación entre procesos, la memoria compartida parece ser la forma más rápida de hacerlo. Una vez que la memoria se asigna al espacio de direcciones en la región de memoria, no se requiere más participación del kernel. ¡Eso es genial! Porque, a diferencia de otros métodos (FIFO, mensajes), subviertes las llamadas al sistema, lo que lo hace increÃblemente rápido.
Repasaremos algunos conceptos básicos de mmap (mapeo de memoria) usando Python. Afortunadamente, Python tiene un módulo incorporado llamado mmap que expone la mayorÃa de las llamadas usando api.
Tengo un archivo de muestra pgm1.go que tiene un programa go simple (no se preocupe, no voy a usar el lenguaje de programación go). Simplemente estamos mapeando el contenido del archivo en la memoria y leyendo su contenido.
import mmap
with open('pgm1.go', 'r+b') as f:
mm = mmap.mmap(f.fileno(),0)
for i in mm:
print mm.readline()
Ahora, ¿cómo verificamos que los datos estén realmente en la memoria? Aquà es donde la herramienta pmap es muy útil. ¡Pero espera un segundo! , no tenemos eso en OS X, ¿verdad? Al menos no soy consciente de ello. Afortunadamente, OS X viene con vmmap, que muestra maravillosamente la misma información.
besidecome-lm:pointers rahulram$ vmmap 71058
==== Summary for process 71058
ReadOnly portion of Libraries: Total=57.9M resident=16.4M(28%) swapped_out_or_unallocated=41.5M(72%)
Writable regions: Total=19.9M written=1936K(10%) resident=2556K(13%) swapped_out=0K(0%) unallocated=17.4M(87%)
REGION TYPE VIRTUAL
=========== =======
MALLOC 11.2M see MALLOC ZONE table below
MALLOC guard page 32K
MALLOC metadata 356K
STACK GUARD 56.0M
Stack 8192K
__DATA 1296K
__LINKEDIT 47.8M
__TEXT 10.0M
__UNICODE 544K
mapped file 4K
shared memory 8K
=========== =======
TOTAL 135.2M
Allà puede ver que el archivo mapeado tiene un tamaño de 4K. En su intérprete de Python, puede
mm.close ()
y ver que vmmap no enumerará esa información. SÃ, confÃo en vmmap y lo doy por sentado: P
Tomemos otro ejemplo que involucra múltiples procesos
import mmap
import os
with open('pgm1.go', 'r+b') as f:
mm = mmap.mmap(f.fileno(),0)
print os.getpid()
pid = os.fork() # Creating a child process
if pid == 0:
mm.seek(0)
print os.getpid()
print os.getppid()
print mm.readline()
mm.close()
El proceso hijo básicamente lee el contenido de mmap y cierra el mismo.
Nota: si el objeto mm se cierra antes de que otros procesos lo usen, comenzará a generar una excepción. Asegúrese de que el objeto mm esté cerrado solo después de descargar el contenido en el disco