threads threading sistemas que programacion operativos hilos desactivado activar activado multithreading asynchronous go io kernel

multithreading - sistemas - hyper threading que es



Al realizar E/S asíncronas, ¿cómo determina el núcleo si se completa una operación de E/S? (1)

El KERNEL a continuación significa "lado del núcleo". Incluye código kernel del sistema operativo + controladores cargados.

Dado que tiene una conexión TCP a un servidor remoto. Aquí hay un ejemplo de cómo Kernel maneja la secuencia de escritura / lectura TCP asíncrona.

Cuando envíe una matriz de bytes a la secuencia TCP, kernel colocará la secuencia de almacenamiento intermedio en la RAM y controlará el sistema DMA para copiar el almacenamiento intermedio en la tarjeta de red. Cuando DMA hizo su trabajo, se invoca una interrupción dentro de la CPU. Un controlador de interrupción registrado por kernel transformará la señal de DMA en una devolución de llamada realizada para escribir en el método de flujo TCP. Por supuesto, la pila de TCP real es mucho más compleja. Estas oraciones son solo una idea de cómo funciona la cosa.

Para el caso leído desde la secuencia TCP, cuando un paquete entra en la tarjeta de red, se invoca otra interrupción. El otro controlador registrado por kernel transformará la interrupción al evento en el lado de golang.

Nuevamente, el caso real es muy muy complejo. Hay muchos sistemas operativos, muchas versiones, muchos tipos de operaciones de E / S y muchos dispositivos de hardware.

Algunos antecedentes sobre por qué estoy preguntando esto. Hice esta pregunta hace unas horas

Cuando un goroutine bloquea en E / S, ¿cómo identifica el planificador que ha dejado de bloquear?

que tenía la respuesta

Todas las E / S deben realizarse a través de llamadas de sistema, y ​​la forma en que las llamadas de sistema se implementan en Ir, siempre se llaman a través de un código controlado por el tiempo de ejecución. Esto significa que cuando llamas a un syscall, en lugar de simplemente llamarlo directamente (renunciando así al control del hilo en el kernel), el tiempo de ejecución es notificado de la llamada al sistema que quieres hacer, y lo hace en nombre del administrador. Esto le permite, por ejemplo, hacer un syscall no bloqueante en lugar de uno de bloqueo (básicamente diciéndole al kernel, "por favor haga esto, pero en lugar de bloquear hasta que esté listo, regrese inmediatamente y avíseme más tarde una vez que el resultado está listo"). Esto le permite continuar haciendo otro trabajo mientras tanto.

Por lo tanto, desde mi entendimiento, lo que hace el programador de golang es que se asegura de no colgarse gastando tiempo en subprocesos a la espera de operaciones de E / S. En cambio, de alguna manera difiere esa responsabilidad para el kernel.

Sin embargo, quiero obtener una comprensión más profunda del proceso porque hay muchas cosas que no están claras para mí.

En este momento, esta es mi comprensión, que puede ser completamente errónea.

  1. Realice una solicitud de E / S, como una solicitud GET, a un servidor remoto dentro de la rutina
  2. Golang hace un syscall para leer una secuencia TCP, que es una operación de bloqueo, pero en lugar de esperar, le pide al kernel que le avise cuando recibe la información. El programador elimina esa rutina de bloqueo de su cola
  3. Cuando el kernel obtiene toda la información, la reenvía al proceso go, y le permite al planificador saber agregar la rutina de regreso a su cola.

Lo que me cuesta entender es cómo se realiza la operación de E / S sin crear otro hilo, y cómo el núcleo realmente "sabe" que la operación de E / S ha terminado. ¿Es a través de las encuestas o hay algún tipo de sistema de interrupción en su lugar?

Espero que esto tenga algo de sentido. Soy muy nuevo en conceptos que tienen este bajo nivel.