Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

513
Visualizações
Project loom, ¿qué sucede cuando el subproceso virtual realiza una llamada al sistema de bloqueo?

Estaba investigando cómo funciona Project Loom y qué tipo de beneficios puede traer a mi empresa.

Así que entiendo la motivación, para el backend estándar basado en servlet, siempre hay un grupo de subprocesos que ejecuta una lógica comercial, una vez que el subproceso se bloquea debido a IO, no puede hacer nada más que esperar. Así que digamos que tengo una aplicación de back-end que tiene un punto final único, la lógica comercial detrás de este punto final es leer algunos datos usando JDBC que internamente usa InputStream que nuevamente usará el bloqueo de llamadas al sistema (read() en términos de Linux). Entonces, si tengo 200 000 usuarios que llegan a este punto final, necesito crear 200 subprocesos cada uno en espera de IO.

Ahora digamos que cambié un grupo de subprocesos para usar subprocesos virtuales en su lugar. Según Ben Evans en el artículo Going inside Java's Project Loom and virtual threads :

En cambio, los subprocesos virtuales abandonan (o ceden) automáticamente su subproceso portador cuando se realiza una llamada de bloqueo (como E/S).

Por lo que tengo entendido, si tengo una cantidad de subprocesos del sistema operativo igual a la cantidad de núcleos de CPU y una cantidad ilimitada de subprocesos virtuales, todos los subprocesos del sistema operativo aún esperarán a IO y el servicio Executor no podrá asignar nuevo trabajo para subprocesos virtuales porque no hay hilos disponibles para ejecutarlo. ¿En qué se diferencia de los subprocesos normales? Al menos para los subprocesos del sistema operativo, puedo escalarlo a miles para aumentar el rendimiento. ¿O acabo de entender mal el caso de uso de Loom? Gracias por adelantado

Añadir

Acabo de leer esta lista de correo :

A los subprocesos virtuales les encanta bloquear E/S. Si el subproceso necesita bloquearse, por ejemplo, una lectura de socket, esto libera el subproceso del núcleo subyacente para hacer otro trabajo

No estoy seguro de entenderlo, no hay forma de que el sistema operativo libere el hilo si realiza una llamada de bloqueo como read, para estos fines, el núcleo tiene llamadas al sistema que no bloquean, como epoll, que no bloquea el hilo e inmediatamente devuelve un lista de descriptores de archivos que tienen algunos datos disponibles. ¿La cita anterior implica que, bajo el capó, JVM reemplazará una read de bloqueo con un epoll sin bloqueo si el subproceso que lo llamó es virtual?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

A su primer extracto le falta el punto importante:

En cambio, los subprocesos virtuales abandonan (o ceden) automáticamente su subproceso portador cuando se realiza una llamada de bloqueo (como E/S). Esto es manejado por la biblioteca y el tiempo de ejecución [...]

La implicación es la siguiente: si su código realiza una llamada de bloqueo a la biblioteca (por ejemplo, NIO), la biblioteca detecta que lo llama desde un hilo virtual y convertirá la llamada de bloqueo en una llamada sin bloqueo, estacione el hilo virtual y continúe procesando algún otro código de subprocesos virtuales.

Solo si ningún subproceso virtual está listo para ejecutarse, se estacionará un subproceso nativo.

Tenga en cuenta que su código nunca llama a una llamada al sistema de bloqueo, llama a las bibliotecas Java (que actualmente ejecutan la llamada al sistema de bloqueo). Project Loom reemplaza las capas entre su código y la llamada al sistema de bloqueo y, por lo tanto, puede hacer lo que quiera, siempre que el resultado de su código de llamada sea el mismo.

over 4 years ago · Santiago Trujillo Relatório

0

La respuesta de Thomas Kläger es correcta. Agregaré algunos pensamientos.

Entonces, según tengo entendido, si tengo una cantidad de subprocesos del sistema operativo igual a la cantidad de núcleos de CPU y una cantidad ilimitada de subprocesos virtuales, todos los subprocesos del sistema operativo seguirán esperando IO

No, incorrecto, lo malinterpretas.

Lo que describe es lo que sucede con la tecnología actual de subprocesos en Java. Con un mapeo uno a uno del subproceso de Java al subproceso del sistema operativo host, cualquier llamada realizada en Java que se bloquee (esperando un tiempo relativamente largo por una respuesta) deja al subproceso de host dando vueltas, sin hacer ningún trabajo. Esto no sería un problema si el host tuviera un millón de subprocesos para que otros subprocesos pudieran programarse para trabajar en un núcleo de CPU. Pero los subprocesos del sistema operativo host son bastante caros, por lo que no tenemos un millón, tenemos muy pocos.

Al usar la tecnología Project Loom, la JVM detecta la llamada de bloqueo, como la espera de E/S. Una vez detectada, la JVM aparta ("estaciona") el subproceso virtual mientras espera la respuesta de E/S. La JVM asigna un subproceso virtual diferente a ese subproceso portador del sistema operativo host, de modo que el subproceso "real" pueda continuar realizando el trabajo en lugar de esperar mientras juguetea. Dado que los subprocesos virtuales que viven dentro de la JVM son tan baratos (altamente eficientes tanto con la memoria como con la CPU), podemos tener miles, incluso millones, para que la JVM haga malabarismos.

En su ejemplo de 200 subprocesos, cada uno esperando la respuesta de IO desde las llamadas JDBC a una base de datos, si fueran subprocesos virtuales, todos estarían estacionados dentro de la JVM. Los pocos subprocesos del sistema operativo host utilizados como subprocesos de soporte por su ExecutorService funcionarán en otros panes virtuales que no están bloqueados actualmente. Este estacionamiento y reprogramación de subprocesos virtuales bloqueados y luego desbloqueados es manejado automáticamente por la tecnología Project Loom dentro de la JVM, sin necesidad de intervención por parte de los desarrolladores de aplicaciones Java.

digamos que cambié un grupo de subprocesos para usar subprocesos virtuales

En realidad, no hay un grupo de subprocesos virtuales. Cada hilo virtual es fresco y nuevo, sin reciclaje. Esto elimina la preocupación por la contaminación local del hilo.

 ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor() ; … executorService.submit( someTask ) ; // Every task submitted gets assigned to a fresh new virtual thread.

Para obtener más información, recomiendo ver los videos de presentaciones y entrevistas de Ron Pressler o Alan Bateman, miembros del equipo de Project Loom. Encuentra lo más reciente, ya que Loom ha ido evolucionando.

Y lea el nuevo Java JEP, JEP draft: Virtual Threads (Preview) .

over 4 years ago · Santiago Trujillo Relatório

0

Finalmente encontré una respuesta. Entonces, como dije, por defecto, el método InputStream.read hace una llamada al sistema read() que, de acuerdo con las páginas del manual de Linux, bloqueará el subproceso del sistema operativo subyacente. Entonces, ¿cómo es posible que Loom no lo bloquee? Encontré un artículo que muestra el seguimiento de la pila Entonces, si este bloque de código se ejecutará mediante un hilo virtual

 URLData getURL(URL url) throws IOException { try (InputStream in = url.openStream()) {//blocking call return new URLData(url, in.readAllBytes()); } }

El tiempo de ejecución de JVM lo transformará en el siguiente stacktrace

 java.base/jdk.internal.misc.VirtualThreads.park(VirtualThreads.java:60)//this line parks the virtual thread java.base/sun.nio.ch.NioSocketImpl.park(NioSocketImpl.java:184) java.base/sun.nio.ch.NioSocketImpl.park(NioSocketImpl.java:212) java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:356)//JVM runtime will replace an actual read() into read from java nio package java.base/java.io.InputStream.readAllBytes(InputStream.java:346)

¿Cómo sabe JVM cuándo desbloquear el subproceso virtual? Aquí está el seguimiento de pila que se ejecutará una vez que readAllBytes

 "Read-Poller" #16 java.base@17-internal/sun.nio.ch.KQueue.poll(Native Method) java.base@17-internal/sun.nio.ch.KQueuePoller.poll(KQueuePoller.java:65) java.base@17-internal/sun.nio.ch.Poller.poll(Poller.java:195)

El autor del artículo usa MacOs, Mac usa kqueue como syscall sin bloqueo. Si lo ejecuto en Linux, vería epoll syscall.

Entonces, básicamente, Loom no presenta nada nuevo, bajo el capó es una simple llamada al sistema de epoll con devoluciones de llamada que se pueden implementar usando un marco como Vert.x que usa Netty bajo el capó, pero en Loom la lógica de devolución de llamada está encapsulada con la JVM. tiempo de ejecución que encontré contrario a la intuición, cuando llamo a InputStream.read() espero una llamada al sistema read() correspondiente, pero JVM la reemplazará con llamadas al sistema sin bloqueo.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda