Red de conocimiento informático - Problemas con los teléfonos móviles - Cómo abrir un archivo mmap en ubuntu

Cómo abrir un archivo mmap en ubuntu

Función: void

*mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize);

Inicio del parámetro: Apunta a la dirección inicial de la memoria que se va a asignar, generalmente configurada en NULL, lo que significa que el sistema selecciona automáticamente la dirección y la devuelve después de que la asignación sea exitosa.

Longitud del parámetro: representa la cantidad del archivo que se asigna a la memoria.

Prot parámetro: el método de protección del área de mapeo. Puede ser una combinación de los siguientes métodos:

PROT_EXEC El área mapeada se puede ejecutar

PROT_READ El área mapeada se puede leer

PROT_WRITE El área mapeada se puede ser escrito

PROT_NONE No se puede acceder al área de mapeo

Marcas de parámetros: afecta varias características del área de mapeo. Se debe especificar MAP_SHARED o MAP_PRIVATE al llamar a mmap().

MAP_FIXED Si la dirección señalada por el parámetro inicio no se puede asignar correctamente, se abandonará la asignación y la dirección no se corregirá. En general, se desaconseja el uso de esta bandera.

Los datos escritos por MAP_SHARED en el área asignada se copiarán nuevamente al archivo, y otros procesos que asignan el archivo podrán compartirlos y el archivo original cambiará.

MAP_PRIVATE La operación de escritura en el área mapeada producirá una copia del archivo mapeado, es decir, una "copia al escribir" privada (no se volverá a escribir ninguna modificación en esta área). el contenido del archivo original. Cuando el área de almacenamiento virtual del objeto compartido es un objeto privado, la modificación solo se cambiará en este proceso.

MAP_ANONYMOUS establece un mapeo anónimo. En este momento, se ignorará el parámetro fd, no habrá archivos involucrados y el área mapeada no se podrá compartir con otros procesos.

MAP_DENYWRITE solo permite operaciones de escritura en el área asignada y otras operaciones de escritura directa en el archivo serán rechazadas.

MAP_LOCKED bloquea el área mapeada, lo que significa que el área no se intercambiará.

Parámetro fd: el descriptor del archivo que se asignará a la memoria. Si se utiliza una asignación de memoria anónima, es decir, MAP_ANONYMOUS se establece en indicadores y fd se establece en -1. Algunos sistemas no admiten el mapeo de memoria anónimo. Puede usar fopen para abrir el archivo /dev/zero y luego mapear el archivo para lograr el mismo efecto del mapeo de memoria anónimo.

Desplazamiento del parámetro: el desplazamiento de la asignación del archivo, generalmente establecido en 0, lo que significa que la asignación comienza desde el frente del archivo. El desplazamiento debe ser un múltiplo entero del tamaño de paginación.

Valor de retorno:

Si la asignación se realiza correctamente, se devuelve la dirección inicial de memoria del área de asignación; de lo contrario, se devuelve MAP_FAILED(-1) y la causa del error se almacena en errno.

Código de error:

El parámetro EBADF fd no es un descriptor de archivo válido

El permiso de acceso a EACCES es incorrecto. Si es MAP_PRIVATE, el archivo debe ser legible. Si se utiliza MAP_SHARED, PROT_WRITE debe estar presente y el archivo debe poder escribirse.

Uno de los parámetros de inicio, longitud o desplazamiento de EINVAL es ilegal.

El archivo EAGAIN está bloqueado o hay demasiada memoria bloqueada.

ENOMEM Sin memoria.

La llamada al sistema mmap() se utiliza para compartir memoria de dos formas:

(1) Utilice la asignación de memoria proporcionada por archivos normales:

Aplicable entre cualquier proceso.

En este momento, necesita abrir o crear un archivo y luego llamar a mmap()

El código de llamada típico es el siguiente:

fd=open(nombre, bandera, modo) ; if(fd< 0) ...

ptr=mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0

Utilice mmap() para realizar compartidos); comunicación de memoria Este método tiene muchas características y cosas a las que prestar atención. Puede consultar el Volumen 2 de Programación de red UNIX.

(2) Utilice archivos especiales para proporcionar mapeo de memoria anónimo:

Aplicable a procesos con afinidad. Debido a la afinidad especial entre los procesos padre e hijo, primero se llama a mmap() en el proceso padre y luego a

fork(). Luego, después de llamar a fork (), el proceso hijo hereda el espacio de direcciones asignado anónimamente del proceso padre y también hereda la dirección devuelta por mmap (). De esta manera, los procesos padre e hijo pueden comunicarse a través del área de mapeo. >

dominio . Tenga en cuenta que esta no es una relación de herencia general. En términos generales, el proceso hijo mantiene de forma independiente algunas variables heredadas del proceso padre. La dirección devuelta por mmap() la mantienen conjuntamente los procesos padre e hijo.

La mejor manera de lograr memoria compartida para procesos con afinidad debería ser utilizar un mapeo de memoria anónimo. En este punto, no es necesario especificar un archivo específico, simplemente configure el indicador apropiado.

Escriba una demostración a continuación:

[html] ver copia simple

#include

#include

#include

#include

//#include "csapp.h"

#include

#include

#include

#include

void mmapcopy(int fd, int size)

{

char *bufp

/ /void * start_addr = 0;

//start_addr = (void *)0x80000;

bufp = mmap(NULL, tamaño, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if (bufp == (void *)-1)

fprintf(stderr, "mmap: %s\n", strerror(errno)); p> memcpy(bufp, "Linuxdd", 7);

write(1, bufp, tamaño

munmap(bufp, tamaño

); retorno;

}

int main(int argc, char **argv)

{

struct stat stat; >

if (argc != 2)

{

printf("error.\n");

exit(0); p> p>

}

//int fd = atoi(*argv[1]

//mmap()

int fd); = open (argv[1], O_RDWR, 0); // O_RDWR se puede leer y escribir.

if (fd < 0)

fprintf(stderr, "open: %s\n", strerror(errno)); // Es un buen hábito utilizar la comprobación de excepciones. ¡Él puede ayudar a los programadores a localizar errores rápidamente!

fstat(fd, &stat);

mmapcopy(fd, stat.st_size

//mientras(1); > cerrar(fd);

salir(0);

}