Domanda

Nel mio codice ci sono tre concorrenti routine.Cerco di dare una breve panoramica del mio codice,

Routine 1 {
do something

*Send int to Routine 2
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 2 {
do something

*Send int to Routine 1
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 3 {
do something

*Send int to Routine 1
Send int to Routine 2
Print Something
Print Something*

do something
}

main {
routine1
routine2
routine3
}

Voglio che, mentre tutti i codici tra due fare qualcosa (codici tra due stelle di marchi) è in esecuzione, il flusso di controllo, non devono andare in altri andare routine.Per esempio, quando routine1 è l'esecuzione di eventi tra due stelle (invio e stampa, eventi), di routine 2 e 3 deve essere bloccato, significa flusso di esecuzione non passa di routine di 2 o 3 dalla routine 1).Dopo aver completato l'ultima stampa evento, il flusso di esecuzione può passare alla routine di 2 o 3.C'è qualcuno che può aiutarmi, specificando, come posso realizzare questo ?È possibile implementare le specifiche da WaitGroup ?Qualcuno può mostrarmi dando un semplice esempio di come implementare sopra specificato esempio utilizzando WaitGroup.Grazie.

NB:Può essere questo è ripetere la domanda di questo.Ho provato utilizzando la sincronizzazione del meccanismo di bloccaggio, tuttavia, può essere perché ho un grande codice perché non potevo mettere il blocco-sblocco correttamente, e creando situazione di stallo (o può essere il mio metodo è errore di produzione).C'è qualcuno che può aiutarmi con una semplice procedura, quindi, sono in grado di ottenere questo. Faccio un semplice esempio del mio codice qui Qui, dove voglio mettere due stampa e l'invio di evento all'interno di mutex (per l'ordinaria 1) così di routine 2 non possono interromperlo.Mi potete aiutare, come è possibile.Una possibile soluzione, http://play.golang.org/p/-uoQSqBJKS che dà errore.

È stato utile?

Soluzione

Perchè vuoi fare questo?

Il problema del deadlock è che se non si consente di programmare altre goroutine, allora il canale non può procedere, a meno che non ci sia buffering. I canali di Go hanno un buffering finito, quindi si finisce con una condizione di gara per drenare prima che vengano inviati mentre sono pieni. Potresti introdurre un buffering infinito o mettere ogni invio nella propria goroutine, ma si riduce di nuovo a: perché stai cercando di farlo; Cosa stai cercando di ottenere?

Un'altra cosa: se si desidera garantire solo l'esclusione reciproca dei tre set di codice tra *s, allora sì, puoi usare i mutex. Se vuoi assicurarlo No Il codice interrompe il blocco, indipendentemente da dove sia stato sospeso, potrebbe essere necessario utilizzare Runtime.lockosthread e runtime.unlockosthread. Questi sono abbastanza bassi e devi sapere cosa stai facendo e raramente sono necessari. Di cui vuoi che non ci siano altre goroutine in esecuzione, dovrai avere runtime.gomaxProcs (1), che è attualmente l'impostazione predefinita.

Altri suggerimenti

Il problema a rispondere alla sua domanda è che sembra che nessuno capisce che cosa il vostro problema è davvero.Vedo che ti stai chiedendo ripetutamente circa lo stesso, anche se nessun progresso è stato fatto.Non c'è offesa nel dire questo.È un tentativo di aiutare un suggerimento per riformulare il problema in un modo comprensibile per gli altri.Come un simpatico effetto collaterale di alcuni problemi non si risolvono, mentre viene spiegato agli altri in modo comprensibile.Ho sperimentato che molte volte da me.

Un altro suggerimento potrebbe essere il sospetto mix di esplicita la sincronizzazione e il canale di comunicazione.Questo non significa che il design è necessariamente rotto.Non accade appena in un tipico/semplice caso.Ancora una volta, il tuo problema potrebbe essere operazioni atipiche/non banale.

Forse è in qualche modo possibile ridisegnare il problema utilizzando solo i canali.In realtà, credo che ogni problema che coinvolge sincronizzazione esplicita (Go) potrebbe essere codificata utilizzando solo i canali.Detto questo, è vero che alcuni problemi sono scritti con sincronizzazione esplicita molto facilmente.Anche il canale di comunicazione, come è a buon mercato come è, non è così a buon mercato come la maggior parte di primitive di sincronizzazione.Ma che potrebbe essere visto dopo più tardi, quando il codice funziona.Se il "modello" per alcuni dicono di sincronizzazione.Mutex visibilmente emergere nel codice, dovrebbe essere possibile cambiare e molto più facile da fare che, quando il codice funziona già e si spera prove di guardare i tuoi passi mentre ad effettuare le regolazioni.

Provate a pensare al vostro goroutines come agire in modo indipendente agenti che:

  • Esclusivamente i propri dati ricevuti dal canale.La lingua non applicare questo, è necessario distribuire la propria disciplina.
  • Non tocco più i dati che ho inviato a un canale.Segue dalla prima regola, ma abbastanza importante per essere più espliciti.
  • Interagire con altri agenti (goroutines) dai tipi di dati, che racchiudono in sé una intera unità di flusso di lavoro/calcolo.Questo elimina es.precedente lotta con geting il numero di messaggi di canale prima di "unità" è completo.
  • Per ogni canale da utilizzare, deve essere assolutamente chiaro in prima se il canale deve essere unbuffered, devono essere memorizzati per il numero fisso di elementi o, se può essere slegato.
  • Non devono pensare (so), su quali altri agenti stanno facendo al di sopra di ricevere un messaggio da loro, se è necessario per l'agente per eseguire il suo compito - parte di un quadro più ampio.

Utilizzando anche ad alcune regole del pollice, si spera, dovrebbe produrre codice che è più facile per la ragione che di solito non richiede di qualsiasi altro sincronizzazione.(Sto volutamente ignorando i problemi di prestazioni delle applicazioni mission critical ora).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top