Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

196
Vistas
Salida de progreso paralelo de subprocesos concurrentes

Tener este código:

 workers = (1..3).map do |n| Thread.new do puts print "Worker_#{n}..." sleep rand print "done (#{n})" end end.each &:join puts puts '- ready -'

¿Cómo podemos obtener una salida correcta como esta (líneas actualizadas dinámicamente):

 Worker_1...done (1) Worker_2...done (2) Worker_3...done (3) - ready -

y no así:

 Worker_1... Worker_2... Worker_3...done (3)done (1)done (2) - ready -

Opción avanzada: si redirigimos la salida estándar al archivo, también debería verse bien.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Introduciría alguna clase para administrar la salida. También moverá el carro 3 líneas arriba para actualizar la salida cada vez (en el método de print ).

 class StatusPrint def initialize @hash = {} end def declare_worker(name) @hash[name] = "Worker_#{name}" end def complete_worker(name) @hash[name] += "...done (#{name})" end def print(move_carriage: true) puts "\033[#{@hash.size + 1}A" if move_carriage puts @hash.values.join("\n") end def done! @done = true end def done? @done end end

Entonces tu código se verá así

 status_print = StatusPrint.new workers = (1..3).map do |n| Thread.new do status_print.declare_worker(n) sleep rand status_print.complete_worker(n) end end print_loop = Thread.new do status_print.print(move_carriage: false) until status_print.done? sleep 0.1 status_print.print end end workers.each &:join status_print.done! print_loop.join puts '- ready -'

Además, no funcionará si desea canalizar su salida, por lo que deberá agregar alguna opción de línea de comando para deshabilitar la actualización de la salida e imprimir este texto estático:

 Worker_1...done (1) Worker_2...done (2) Worker_3...done (3) - ready -

Consulte también https://blog.stevenocchipinti.com/2013/06/removing-previously-printed-lines.html/ para obtener más información sobre cómo actualizar la salida.

over 4 years ago · Santiago Trujillo Denunciar

0

Finalmente, he creado una gema para resolver este problema:

Gema de rubí ParaLines

Muestra de salida:
ingrese la descripción de la imagen aquí

Algunas muestras de uso mínimo se ven así:

 require 'paralines' plines = ParaLines.new plines.add_static_line 'Gems latest versions' plines.add_empty_line gems = %w[sinatra rspec paralines rails hanami] plines.add_static_line '- Random order:' threads = gems.map do |name| Thread.new do plines << name.ljust(15, '.') res = `gem list -r #{name} -e` plines << 'v' + res[/\((.+)\)/, 1] end end sleep 0.2 plines.add_empty_line plines.add_static_line '- Sorted:' threads += gems.sort.map do |name| sline = plines.add_shared_line name.ljust(15, '.') Thread.new do res = `gem list -r #{name} -e` sline << 'v' + res[/\((.+)\)/, 1] end end threads.each &:join

El código fuente de la muestra detallada con salida como en la animación GIF se puede encontrar en la página de la gema en GitHub .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda