Cómo retrasar adecuadamente la ejecución entre un grupo de trabajadores.
Buen día,
Estoy tratando de implementar el retraso correcto entre la ejecución de los trabajadores. Por ejemplo, es necesario que los trabajadores completen 30 tareas y luego se duerman durante 5 segundos. ¿Cómo puedo rastrear en el código que se han completado exactamente 30 tareas y solo después de eso dormir durante 5 segundos?
A continuación se muestra el código que crea un grupo de 30 trabajadores, quienes a su vez realizan tareas de 30 piezas a la vez de manera desordenada, aquí está el código:
“`package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
type Job struct {
id int
randomno int
}
type Result struct {
job Job
sumofdigits int
}
var jobs = make(chan Job, 10)
var results = make(chan Result, 10)
func digits(number int) int {
sum := 0
no := number
for no != 0 {
digit := no % 10
sum += digit
no /= 10
}
time.Sleep(2 * time.Second)
return sum
}
func worker(wg *sync.WaitGroup) {
for job := range jobs {
output := Result{job, digits(job.randomno)}
results <- output
}
wg.Done()
}
func createWorkerPool(noOfWorkers int) {
var wg sync.WaitGroup
for i := 0; i < noOfWorkers; i++ {
wg.Add(1)
go worker(&wg)
}
<pre><code>wg.Wait()
close(results)
</code></pre>
}
func allocate(noOfJobs int) {
for i := 0; i < noOfJobs; i++ {
if i != 0 && i%30 == 0 {
fmt.Printf("ESPERANDO 5 segundos…")
time.Sleep(10 * time.Second)
}
<pre><code> randomno := rand.Intn(999)
job := Job{i, randomno}
jobs <- job
}
close(jobs)
</code></pre>
}
func result(done chan bool) {
for result := range results {
fmt.Printf("ID de trabajo %d, número aleatorio de entrada %d, suma de los dígitos %d\n", result.job.id, result.job.randomno, result.sumofdigits)
}
done <- true
}
func main() {
startTime := time.Now()
noOfJobs := 100
go allocate(noOfJobs)
done := make(chan bool)
go result(done)
noOfWorkers := 30
createWorkerPool(noOfWorkers)
<-done
endTime := time.Now()
diff := endTime.Sub(startTime)
fmt.Println("tiempo total transcurrido", diff.Seconds(), "segundos")
}
“`
Juega: https://go.dev/play/p/lehl7hoo-kp
No está claro cómo asegurarse de que se completen 30 tareas y dónde insertar el retraso. Agradeceré cualquier ayuda.
davy.ai
Para hacer un seguimiento de que exactamente se han completado 30 tareas y solo después de eso dormir durante 5 segundos, puedes hacer uso de un contador.
Primero, inicializa un contador en 0 fuera de la función “allocate”.
Luego, dentro de la función “worker”, incrementa el contador cada vez que se completa una tarea utilizando “atomic.AddInt32” del paquete “sync/atomic” para garantizar la seguridad de las hebras.
Una vez que el contador llega a 30, la función “allocate” puede dormir durante 5 segundos antes de continuar asignando más trabajos.
Aquí está el código modificado:
Puedes ver el ejemplo funcional aquí: https://go.dev/play/p/TjhTQJGL9X9.