Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

260
Views
Cómo ejecutar hilos en orden en Ruby

Tengo una tarea donde tengo 2 números (a y b) y un conteo (n). Primero necesito generar números aleatorios que serán el tiempo que cada subproceso dormirá. Luego, cada subproceso calcula la suma, la diferencia, el producto y la división (respectivamente) de a y b y lo repite n veces. Por ejemplo:

 a = 10 b = 2 n = 2 SUM: 12 DIFFERENCE: 8 PRODUCT: 20 DIVISION: 5 SUM: 12 DIFFERENCE: 8 PRODUCT: 20 DIVISION: 5

y entre cada línea, el programa duerme por unos segundos. El orden debe ser suma, diferencia, producto y división. No puedo usar colas o matar/generar hilos repetidamente. Mi primer pensamiento fue usar 4 variables condicionales para dictar el orden en que deben ejecutarse los subprocesos. Se me ocurrió esto:

 mutex = Mutex.new resources = Array.new(4) { ConditionVariable.new } t1 = Thread.new do mutex.synchronize do puts "Thread 1" sleep(3) resources[0].signal end end t2 = Thread.new do mutex.synchronize do resources[0].wait(mutex) puts "Thread 2" sleep(3) resources[1].signal end end t3 = Thread.new do mutex.synchronize do resources[1].wait(mutex) puts "Thread 3" sleep(3) resources[2].signal end end t4 = Thread.new do mutex.synchronize do resources[2].wait(mutex) puts "Thread 4" sleep(3) end end t1.join t2.join t3.join t4.join

pero recibo este error de interbloqueo: main.rb:39:in 'join': No live threads left. Deadlock? (fatal)

¿Podría funcionar este enfoque? ¿Qué debo hacer para arreglarlo? ¿Hay otros enfoques mejores que podrían funcionar?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

No soy un experto en rubíes, pero en todos los demás idiomas que he usado, el nombre " variable de condición" es inapropiado. Para cualquier otra cosa que se llame "variable", esperamos que si un subproceso la cambia, algún otro subproceso puede aparecer más tarde y ver que se modificó. No es así como funcionan las variables de condición.

Cuando el subproceso A "notifica/señala" una variable de condición, "despertará" algún otro subproceso que ya estaba esperando, pero si no hubo otro subproceso esperando en ese momento, entonces la señal/notificación no hace absolutamente nada.

Las variables de condición no recuerdan las notificaciones.

Esto es lo que creo que podría pasar:

El subproceso t1 bloquea el mutex y luego duerme.

Los otros tres subprocesos se inician y todos se bloquean mientras esperan el mutex.

El subproceso t1 regresa de sleep(3) y señala la variable de condición. Pero, las variables de condición no recuerdan las notificaciones. Ninguno de los otros subprocesos ha podido llegar a sus llamadas de wait(mutex) , porque todavía están tratando de pasar mutex.synchronize . Se pierde la notificación.

El subproceso t1 abandona el bloque sincronizado, los otros subprocesos ingresan a sus bloques sincronizados, uno por uno, hasta que todos están esperando señales.

Mientras tanto, el hilo principal ha estado colgado en t1.join() . Esa llamada regresa cuando finaliza el subproceso t1 , pero luego el subproceso principal llama a t2.join() t2 está esperando una señal, t3 está esperando una señal, t4 está esperando una señal y el subproceso principal está esperando que t2 muera.

No más hilos en vivo.


Nuevamente, no soy un experto en rubí, pero en todos los demás idiomas, un hilo que usa una variable de condición para esperar alguna "condición" debe hacer algo como esto:

 # The mutex prevents other threads from modifying the "condition" # (ie, prevents them from modifying the `sharedData`.) mutex.lock() while ( sharedData.doesNotSatisfyTheCondition() ) { # The `wait()` call _temporarily_ unlocks the mutex so that other # threads may make the condition become true, but it's _guaranteed_ # to re-lock the mutex before it returns. conditionVar.wait(mutex) } # At this point, the condition is _guaranteed_ to be true. sharedData.doSomethingThatRequiresTheConditionToBeTrue() mutex.unlock()

Lo más importante que sucede aquí es que la persona que llama no espera si la condición ya es verdadera. Si la condición ya es verdadera, es probable que la notificación ya haya ocurrido. Nos lo perdimos, y si lo esperamos ahora, podemos terminar esperando para siempre.

La otra cosa importante es que, después de esperar y recibir una notificación, verificamos la condición nuevamente. Dependiendo de las reglas del lenguaje de programación, del sistema operativo y de la arquitectura del programa; es posible que wait() regrese prematuramente.


Hacer que la condición se cumpla es simple:

 mutex.lock() sharedData.doSomethingThatMakesTheConditionTrue() conditionVar.notify() mutex.unlock()
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!