Conceptos básicos de la entrevista: principio de comunicación del proceso Binder

Primero, hablemos brevemente sobre todos los métodos IPC entre procesos existentes en Linux:

Pipe (Pipe): asigne una memoria del tamaño de una página al crear y compare los tamaños del búfer Limitado

Cola de mensajes (Mensaje): copia información dos veces, consumo adicional de CPU; no es adecuado para comunicaciones frecuentes o de gran cantidad de información

***Compartir memoria): no es necesario; para copiar, el búfer compartido se adjunta directamente al espacio de direcciones virtuales del proceso, lo cual es rápido, sin embargo, el sistema operativo no puede solucionar el problema de sincronización entre procesos y cada proceso debe usar herramientas de sincronización para resolverlo.

Socket: Como interfaz más general, la eficiencia de transmisión es baja y se utiliza principalmente para la comunicación entre diferentes máquinas o entre redes.

Semáforo: A menudo se utiliza como mecanismo de bloqueo para evitar que otros procesos accedan al recurso cuando un proceso accede a un recurso compartido. Por tanto, se utiliza principalmente como medio de sincronización entre procesos y entre diferentes subprocesos dentro de un mismo proceso.

Señal: No adecuada para el intercambio de información, pero más adecuada para el control de interrupciones de procesos, como acceso ilegal a la memoria, finalización de un proceso, etc.

Amplíe el análisis de Binder desde 4 perspectivas

(1) Desde una perspectiva de rendimiento

Número de copias de datos: la copia de datos de Binder solo necesita una vez y Las canalizaciones, las colas de mensajes y los sockets requieren dos tiempos, pero el método de memoria compartida no requiere una copia de memoria desde una perspectiva de rendimiento. El rendimiento de Binder es superado solo por la memoria compartida;

(2) Desde la perspectiva de la estabilidad

Binder se basa en la arquitectura C/S. La arquitectura es clara y clara. El lado del servidor y el lado del cliente son relativamente independientes y tienen buenas características. estabilidad; y* ** La implementación de la memoria compartida es compleja y no hay diferencia entre el cliente y el servidor. Es necesario considerar completamente la sincronización concurrente del acceso a recursos críticos; de lo contrario, pueden ocurrir interbloqueos y otros problemas; Desde una perspectiva de estabilidad, la arquitectura Binder es superior a** *Disfruta de la memoria.

(3) Desde una perspectiva de seguridad

El receptor del IPC de Linux tradicional no puede obtener el UID/PID confiable del proceso de la otra parte y, por lo tanto, no puede identificar la identidad de Android de la otra parte; Como sistema de código abierto, la seguridad de los teléfonos móviles es particularmente importante. Cualquier medida de protección en el Linux IPC 5 tradicional está completamente garantizada por el protocolo de capa superior.

Android asigna su propio UID a cada aplicación instalada, por lo que el UID del proceso es un símbolo importante para identificar la identidad del proceso. Como se mencionó anteriormente, en la arquitectura C/S, solo el Cliente está expuesto al mundo exterior en el sistema Android. El Cliente envía tareas al Servidor. El Servidor determinará si el UID/PID cumple con los permisos de acceso. política de control Actualmente, el control de permisos a menudo se realiza mediante Aparece un cuadro de diálogo de consulta de permisos que permite al usuario elegir si desea ejecutarlo.

El IPC tradicional solo puede permitir a los usuarios completar UID/PID en los paquetes de datos; además, las etiquetas de identidad confiables solo pueden agregarse en el kernel mediante el propio mecanismo de IPC. En segundo lugar, los puntos de acceso tradicionales de IPC están desarrollados y no pueden establecer canales privados. Desde una perspectiva de seguridad, Binder es más seguro.

(4) Desde la perspectiva del lenguaje

Todo el mundo sabe que Linux se basa en el lenguaje C (lenguaje orientado a procesos), mientras que Android se basa en el lenguaje Java (declaración orientada a objetos) . Binder está exactamente en línea con el pensamiento orientado a objetos: convierte la comunicación entre procesos en una referencia a un objeto Binder y llama al método del objeto. Su característica única es que el objeto Binder es un objeto al que se puede hacer referencia en todos los procesos. Su entidad está ubicada en un proceso, pero sus referencias están distribuidas en todos los procesos del sistema.

Binder difumina los límites del proceso y minimiza el proceso de comunicación entre procesos, haciendo que todo el sistema parezca estar ejecutándose en el mismo programa orientado a objetos.

El marco de Binder define cuatro roles: servidor, cliente, ServiceManager (en lo sucesivo, SM) y controlador de Binder. Entre ellos, Servidor, Cliente y SM se ejecutan en el espacio del usuario y el controlador se ejecuta en el espacio del kernel.

ServiceManager y Binder de nombre real

El cliente obtiene una referencia al Binder de nombre real

Después de que el servidor registra la entidad Binder y su nombre con SM, el cliente puede obtener la entidad de Binder por su nombre.

Carpeta anónima

No todas las carpetas necesitan estar registradas y anunciadas en SM. El Servidor puede pasar la entidad Binder creada al Cliente a través de la conexión Binder establecida. Por supuesto, esta conexión Binder establecida debe implementarse a través de un Binder de nombre real. Dado que este Encuadernador no ha registrado su nombre en SM, es un Encuadernador anónimo. El Cliente recibirá una referencia a este Carpeta anónima y enviará una solicitud a la entidad ubicada en el Servidor a través de esta referencia. Anonymous Binder establece un canal privado para ambas partes que se comunican. Siempre que el servidor no envíe el Binder anónimo a otros procesos, otros procesos no pueden obtener una referencia al Binder a través de métodos exhaustivos o de adivinación y enviar solicitudes al Binder.

En el método IPC tradicional, ¿cómo llegan los datos desde el extremo emisor al extremo receptor? El enfoque habitual es: el remitente almacena los datos preparados en el área del búfer e ingresa al kernel a través de llamadas API del sistema. El programa de servicio del kernel asigna memoria en el espacio del kernel y copia datos del búfer del remitente al búfer del kernel. El receptor también necesita proporcionar un área de búfer al leer datos. El núcleo copia los datos del área de búfer del núcleo al área de búfer proporcionada por el receptor y activa el hilo receptor para completar una transmisión de datos. Este mecanismo de almacenamiento y reenvío tiene dos defectos: primero, es ineficiente y requiere dos copias (espacio de usuario-gt; espacio de kernel-gt; espacio de usuario). Linux usa copy_from_user() y copy_to_user() para implementar estas dos copias entre espacios. En segundo lugar, el búfer para recibir datos debe ser proporcionado por el receptor, pero el receptor no sabe qué tamaño de búfer se necesita. Solo puede abrir la mayor cantidad de espacio posible o llamar primero a la API para recibir el encabezado del mensaje para obtener el tamaño del cuerpo del mensaje y luego abrir el espacio apropiado para recibir el cuerpo del mensaje. Ambos enfoques tienen desventajas: o son una pérdida de espacio o de tiempo.

Binder adopta una nueva estrategia: el controlador de Binder se encarga de gestionar la caché de recepción de datos. El controlador Binder crea un espacio de caché para la recepción de datos implementando mmap().

De esta forma, el receptor de Binder tendrá un área de búfer de recepción con un tamaño de MAP_SIZE. El valor de retorno de mmap() es la dirección de la memoria asignada en el espacio del usuario, pero este espacio lo administra el controlador y los usuarios no necesitan acceder a él directamente (el tipo de asignación es PROT_READ, asignación de solo lectura).

Referencias

Principio del mecanismo de Android Binder (la comprensión más sólida de la historia, nadie)

rved