2014-07-11 15 views
6

Penso che questa sia più una domanda sulla logica che andare da sé. Voglio trovare un modo per eseguire un'attività in base alle sue dipendenze nella lingua go.Esegui attività in base alle dipendenze in Go

Task Workflow

Considerando il workflow sopra: Task 1,2,3 e 4 possono essere corse asincrono allo stesso tempo. L'attività 10 verrà eseguita al termine delle attività 1 e 2. L'attività 11 verrà eseguita al termine delle attività 3 e 4 L'attività 12 verrà eseguita quando l'attività 11 e 12 è terminata L'attività 100 verrà eseguita quando l'attività 10 e 11 terminano.

Sto utilizzando i canali di go per eseguire le esecuzioni simultanee e voglio trovare un modo efficace per controllare le dipendenze. So che potrei avere una sorta di flag e un tavolo per controllare l'esecuzione, ma idealmente mi piacerebbe farlo in memoria per evitare che le chiamate al database controllino tale cosa. Capisco anche che ci sono diversi modi per farlo, ma mi piacerebbe sentire le tue idee perché sono sicuro che c'è un modo migliore di fare rispetto ai modi in cui ho potuto arrivare fino ad ora.

risposta

5

C'è stato un interessante reddit thread su questo argomento, in risposta all'articolo "How to Wait for All Goroutines to Finish Executing Before Continuing".

L'articolo corretto è "How to Wait for All Goroutines to Finish Executing Before Continuing, Part Two: Fixing My Oops" e illustra diversi modi di attendere le goroutine prima di proseguire con un'altra attività.

A seconda del tipo di informazioni disponibili per le attività da sincronizzare, sync.WaitGroup è un buon candidato (come in this example).

Ma:

Quando si conosce il numero di messaggi aspettarsi si potrebbe anche contare loro di sapere quando a finire. Qui il WaitGroup è superfluo e confuso.

Questo bloccherebbe fino a quando tutti 3 messaggi vengono ricevuti:

func main() { 
    messages := make(chan int) 
    go func() { 
     time.Sleep(time.Second * 3) 
     messages <- 1 
    }() 
    go func() { 
     time.Sleep(time.Second * 2) 
     messages <- 2 
    }() 
    go func() { 
     time.Sleep(time.Second * 1) 
     messages <- 3 
    }() 
    for i := 0; i < 3; i++ { 
     fmt.Println(<-messages) 
    } 
} 

Così è in realtà dipende da ciò che si sa dai compiti che si sta aspettando.

+0

Il problema è che non voglio attendere che TUTTE le routine simultanee finiscano. Ad esempio, se le attività 1,2,3 e 4 possono essere eseguite contemporaneamente. Diciamo che l'attività 1,2,3 impiega 10 secondi per terminare e l'attività 4 richiede 10 minuti. In questo caso, l'attività 11 deve ancora attendere Task4, tuttavia il processo può proseguire ed eseguire l'attività 10, che dipende solo dalle attività 1 e 2. Se aspetto che tutte le routine finiscano, l'attività 10 attenderà l'attività 4, che non è corretta perché non dipendono l'una dall'altra. –

+0

@ J.B il mio punto era di illustrare come lavorare su * n * numero di goroutine. Se "n" nel tuo caso è 1,2 e 3, allora la mia risposta è valida. È possibile adattare i vari metodi di sincronizzazione a cui faccio riferimento nella risposta a qualsiasi numero di goroutine desiderato. – VonC

Problemi correlati